Moisés Gualapuro - moises.gualapuro@ikiam.edu.ec - Universidad Regional Amazónica IKIAM, Tena (Ecuador)
Al finalizar la unidad, el estudiante será capaz de:
Instalar R y Rstudio en el equipo personal
Crear su usuario en Rstudio cloud (https://rstudio.cloud/)
Tener familiaridad con el entorno de Rstudio
Utilizar las operaciones matemáticas fundamentales.
Identificar los tipos de datos comunes en R.
Operar con los diferentes tipos de datos en R.
Utilizar data precargada en R
Condicional if
Bucle while
Bucle for
Funciones
Manipulación de datos
Data precargada
Importación de datos
Manipulación de datos
Manipulación de data grande
R es un lenguaje de programación para estadística computacional. Es un paquete de software libre disponible bajo GNU Licencia General Pública. R y sus librerías están diseñadas para estadística y visualización, entre ellas las estadísticas descriptivas, inferencias estadísticas y análisis de regresión.
Es compatible con todos los sistemas operativos (Linux, MacOS, Windows).
Es un entorno integrado, especialmente desarrollado para el análisis de datos, los cálculos estadísticos y las representaciones gráficas.
Es un lenguaje de programación sencillo.
Es software libre.
Ampliamente usado en la investigación científica.
Permite crear visualizaciones de datos de alta calidad (ggplot).
Permite crear dashboards para visualizar y analizar datos (Markdown, rKnit, Latex).
Permite crear informes automáticos.
Dispone de herramientas de análisis estadístico para ahondar en el conocimiento de los datos.
Es reproducible.
Interactividad en la visualización (shiny: https://shiny.rstudio.com/gallery/, plot.ly: https://plot.ly/r/line-and-scatter/).
Comunidad de apoyo (StackOverflow: https://stackoverflow.com/questions/tagged/r, cross Validated: https://stats.stackexchange.com/, R Help Mailing List: https://stat.ethz.ch/mailman/listinfo/r-help, r-bloggers: https://www.r-bloggers.com/).
Amplia disponibilidad de paquetes (https://cran.r-project.org/web/packages/available_packages_by_name.html, tidyverse: https://www.tidyverse.org/).
Amplia disponibilidad de paquetes para ciencias de la vida (https://www.bioconductor.org/).
R podría consumir toda la memoria RAM disponible, dificulta el trabajo con datos masivos.
No se puede reclamar si algo no funciona.
La calidad de algunos paquetes puede no ser ideal.
Al inicio no es user-friendly. La curva de aprendizaje es lenta al inicio, luego es exponencial.
Fácil equivocarse y no reconocer dónde se encuentra el error.
R se puede descargar de https://cran.r-project.org; luego se debe seguir las instrucciones e instalar con las opciones predeterminadas.
En Ubuntu se ejecuta en el terminal: sudo apt-get install r-base.
Después de instalar R, se debe instalar RStudio desde: https://rstudio.com/products/rstudio/download/; se debe seguir las instrucciones e instalar con las opciones predeterminadas.
Ingresar a https://rstudio.cloud y crear un usuario como en cualquier plataforma de correo o red social.
La primera opción es abrir la consola de R base:
La segunda opción es abrir el terminal (Ctrl + Alt + t) o la línea de comando (cmd)
La tercera opción es usar R con RStudio.
“RStudio es un integrated development environment (IDE) para R. Incluye una consola, editor con resaltador-sintáctico que soporta la ejecución de código, asimismo herramientas de gráfica, registro histórico, debugging y administración del entorno de trabajo (workspace)”
Al abrir RStudio se tendrá la siguiente ventana:
En el interfaz de RStudio se tiene 4 áreas, además de la barra de opciones en la parte superior.
Área Superior - Izquierda: es el editor de sintaxis; se trata del lugar donde editamos la sintaxis para posteriormente ejecutarla. Al escribir allí no sucederá nada, a no ser que se apriete algún botón para ejecutar los comandos o la tecla ctrl+enter.
Área Superior - Derecha: es el “entorno de trabajo” del programa: en este lugar se muestra el conjunto de datos y los “objetos” (resultados, variables, gráficos, etc.) que se almacenan al ejecutar diferentes análisis.
Área Inferior - Derecha: paneles de archivos, de salida, de paquetes y de ayuda;
la pestaña files permite ver el historial de archivos trabajados con el programa;
la pestaña plots permite visualizar los gráficos que se generen;
la pestaña packages permite ver los paquetes descargados y guardados en el disco duro así como gestionar su instalación o actualización;
la ventana help permite acceder al CRAN - Comprehensive R Archive Network (siempre que se cuente con conexión a Internet), página oficial del software que ofrece diferentes recursos para el programa: manuales para el usuario, cursos on line, información general, descarga de paquetes, información de los paquetes instalados, etc. Esta última pestaña es bastante útil: empleando el motor de búsqueda se accede de manera rápida a manuales de uso de los diferentes paquetes (y sus funciones) instalados en el computador (esto no requiere conexión a Internet).7;
la ventana viewer muestra los resultados al construir reportes mediante funcionalidades tipo rmarkdown.
Área Inferior - Izquierda: es la consola. Corresponde a lo que sería el software R en su versión básica. Allí el software ejecuta las operaciones realizadas desde el editor de sintaxis.
Las funcionalidades señalados a continuación están disponibles en: https://github.com/rstudio/cheatsheets/blob/master/translations/spanish/rstudio-ide_Spanish_Translation_Monica_Alonso.pdf
Revisión de la versión de R
version## _
## platform x86_64-w64-mingw32
## arch x86_64
## os mingw32
## system x86_64, mingw32
## status
## major 4
## minor 1.2
## year 2021
## month 11
## day 01
## svn rev 81115
## language R
## version.string R version 4.1.2 (2021-11-01)
## nickname Bird Hippie
La versión predertimanada de R tiene varias funciones previamente cargadas. Por otro lado, se tiene funciones más especializadas que se desarrollan en forma de paquetes que se requieren ser instaladas desde el repositorio de R denominada CRAN (https://cloud.r-project.org/). Para revisar el paquete disponible debe dirigirse a la sección “Software/Packages”. Aquí encontrará un aproximado de 16395 paquetes.
Para instalar alguno de ellos se debe usar el código:
# Revisar paquetes instalados
#installed.packages("forensic")
# Instalar un único paquete, install.packages("nombrepaquete")
#install.packages("forensic")
# Grupo de paquetes, install.packages(c("nombrepaquete1", "nombrepaquete2",...))
#install.packages(c("tinytest", "abdiv"))
# Instalar solamente si se requiere
#if(require("forensic")) install.packages("forensic")
# Actualizar un paquete
#update.packages("car")
# Remover o desinstalar paquete(s)
#remove.packages("abdiv")Se puede utilizar la orden help("nombrefuncion") o ?nombrefuncion o ??nombrefuncion_
# Revisar información de ayuda y ejemplos. Se puede escribir:
# Ayuda de una función
?mean
help(mean)
??sqrt
help(sqrt)
# Ayuda de un paquete: Se puede escribir
??ggplotLa información de ayuda se desplegará en la ventana inferior-derecha, donde se muestra la: descripción, usos, argumentos, valores, referencias y ejemplos. Si la función es implementado en varios módulos, se presentará el listado de módulos para seleccionar.
Si la información disponible en Help es insuficiente o no logra corregir algo por cuenta propia, se recomienda hacer la busqueda del tema en plataformas como:
R-project: https://www.r-project.org/help.html
RStudio support: https://community.rstudio.com/
Stackoverflow: https://stackoverflow.com/questions/tagged/r
Cross Validated: https://stats.stackexchange.com/
R-bloggers: https://www.r-bloggers.com/
GitHub: https://github.com/search?l=R&q=R+programming&type=Repositories
| OPERADOR | DESCRIPCIÓN |
|---|---|
+ |
Suma, adición |
- |
Resta, sustracción |
* |
Multiplicación, producto |
/ |
División |
| ^ o ** | Exponenciación |
| `x %% y` | Módulo o remanente |
| `x %/% y` | Dicisión entera |
| `==` | Igual a |
| `!=` | No igual a |
| > | Mayor que |
| < | Menor que |
| >= | Mayor o igual que |
| <= | Menor o igual que |
| & | Lógico “Y” |
| | | Lógico “o” |
| ! | Lógico “no” |
# Suma
3+5## [1] 8
# Resta
5-3## [1] 2
# Multiplicación
3*4## [1] 12
# División
12/3## [1] 4
# Exponente
4^3## [1] 64
exp(2) # valor exp = e = 2.7182818, exp(2)= e^2 =7.389056## [1] 7.389056
# Modulo o restante
3%%2## [1] 1
4%%2## [1] 0
# División entera
18%/%5## [1] 3
# Raíz
sqrt(9)## [1] 3
# Logaritmo (log en base e, log10 en base 10, log2 en base 2)
log(exp(2))## [1] 2
log(7)## [1] 1.94591
log10(1000)## [1] 3
log10(20)## [1] 1.30103
log2(64)## [1] 6
log2(30)## [1] 4.906891
logb(125, base=5)## [1] 3
logb(125, base=3)## [1] 4.394921
# Trigonométricas (escribir los ángulos en radianes)
sin(pi) # valor pi =3.1415927## [1] 0.0000000000000001224606
sin(pi/3)## [1] 0.8660254
cos(pi/4)## [1] 0.7071068
tan(3*pi/5)## [1] -3.077684
Las operaciones de relación comparan el orden de los valores numéricos o alfabéticos y siempre retornan valores booleanosTRUE o FALSE. Por ejemplo, si hacemos la operación 2<5, la respuesta que retorna es TRUE porque el valor 2 es menor que el valor 5. Asimismo, si hacemos la operación "a">"c", la respuesta que retorna es FALSE porque la letra a en el alfabeto se encuentra a la antes que la letra c. Así también se puede comparar palabras "papaya" <"papagayo"
# Menor
3 < 5## [1] TRUE
4 < 6## [1] TRUE
"a" < "c"## [1] TRUE
"d" < "b"## [1] FALSE
# Mayor
2>3## [1] FALSE
3>2## [1] TRUE
"a" > "c"## [1] FALSE
"m" > "b"## [1] TRUE
# Menor o igual que
3<=4## [1] TRUE
4<=8/2## [1] TRUE
"a" <= "b"## [1] TRUE
"m" <= "m"## [1] TRUE
# Mayor o igual que
5>=4## [1] TRUE
2>=8/2## [1] FALSE
"m" >= "b"## [1] TRUE
"p" <= "t"## [1] TRUE
# Igual a
2 == (8/4)## [1] TRUE
# No igual a
3 !=4## [1] TRUE
# Comparar palabras
"papaya" <"papagayo"## [1] FALSE
En estas operaciones se usan operadores lógicos para concatenar operaciones de relación simples y siempre el resultado es TRUE (verdadero, 1) o FALSE (falso, 0). Entre los operadores lógicos fundamentales se tiene:
AND (&) operador “y”, solo cuando las dos operaciones simples son verdaderas resultado de la operación es verdadera. Por ejemplo: 2+3==5 es verdadero y 3^2 >= 9 tambien es verdadero, entonces el resultado de (2+3==5) & (3^2 >= 9) será verdadero.
OR (|) operador “o”, solo si las dos operaciones simples son falsas resulta en falso; si alguno de los es verdadero, entonces la operación es verdad. Por ejemplo: 2+3>5 es falso y 3^2 != 9 tambien es falso, entonces el resultado de (2+3>5) & (3^2 != 9) será falso.
NOT(!) operador “no” o de negación. Cambia el valor lógico de TRUE a !TRUE o FALSE.
# Operador AND
(3<4) & (4/2==2)## [1] TRUE
(3>4) & (4/2==2)## [1] FALSE
(3<4) & (4/2!=2)## [1] FALSE
(3>4) & (4/2!=2)## [1] FALSE
# Operador OR
(3<4) | (4/2==2)## [1] TRUE
(3>4) | (4/2==2)## [1] TRUE
(3<4) | (4/2!=2)## [1] TRUE
(3>4) | (4/2!=2)## [1] FALSE
# Operador NOT
!(3<4)## [1] FALSE
!(3==4)## [1] TRUE
# Combinación AND, OR, NOT
!(3!=4)&((4>=5)|(2>0))## [1] FALSE
En la operacione de asignación se asignan valores a las variables. Los simbolos de asignación son <-, =, <<-, -> y ->>. La primera simbología es la más utilizada en R. Para asignar, se requiere generar los nombres de las variables.
Se recomienda generar el nombre de las variables con palabras que den sentido a los valores a los que hace referencia. También se recomienda utilizar nombres de variables que contengan letras, dígitos ·, _. Asimismo con las siguientes consideraciones:
Iniciar los nombres con una letra ancho, ancho.ala, ancho_ala, anchoAla, anchoAla, ancho.aleta1, ancho.aleta15.
Se puede iniciar con _, pero el caracter inmediato no debe ser dígito. _ancho.aleta1
Evitar el uso de uso de palabras reservadas como TRUE, FALSE, mean, sqrt, if, for, while, function. Éstas palabras tienen significados y funciones especiales y predefinidas en R, por ende no se pueden usar como identificadores. Para consultar otras palabras reservadas digite ?Reserved.
Al asignar valores a los identificadores se crea un objeto y éste se almacena y se visualiza en el espacio de “Environment” (región superior derecha). Constantes:
# Asignación con "<-"
nombre <-"Carlitos"
edad <- 25
cabello <- "negro"
# Asignación con "="
especie = "Zea mays"
variedad = "INIAP29"
mazorcas <- 3
altura_flor <- 150 # medidos en centímetros (cm)
# Asignación con "<<-"
cumbre <<-"Cotopaxi"
altura <<- 5897 # medido en metros
latitud <<- 0.683 # Sur
longitud <<- 78.436 # Oeste
# Asignación con ">-"
vitamina = "Ácido ascórbico" # Vitamina C
organo <- "hígado"
concentracion <<- 7.98 # medidos en mg/L para muestra de la población alemanaPreviamente se asignaron algunos valores a los identificadores. Algunos de los tipos de valores son:
Lógicas (boolean): True, 1 o False, 0
Numérico entero (integer): 17, -10, 213784895
Numérico decimales (double): 1.0, 11.232, pi, 2.718
Numérico complejo (complex): 5-2i
Texto (character): "Los días de la semana", "Bienvenidos"
Categórico (factor): es un tipo de vector que tiene características de grupo y se lo convierte al utilizar as.factor(vector). Algunos ejemplos son: "Excelente", "Muy bueno", "Bueno", "Urbano", "Rural", "Costa", "Sierra", "Amazonía", "Galápagos"
Ausente (missing): NA
Vacío (empty): NULL
Para revisar el tipo de dato se debe usar el comando typeof(dato)
hoy.lunes <- TRUE
casas.manzana2 = as.integer(25)
caudal_rio1 <<- 125.13 # lts/seg
complejo <- 2+3i
carrera <- "Astrobiología"
categorico <- as.factor(c("Bueno", "Excelente", "Regular", "Muy Bueno"))
avances_tesis <- "NA"
marcianos <- ""
fechas <-
variables <- list(hoy.lunes, casas.manzana2, caudal_rio1, complejo,
carrera, categorico, avances_tesis, marcianos)
for (item in variables){
print(paste(item, ": ", typeof(item)))
}## [1] "TRUE : logical"
## [1] "25 : integer"
## [1] "125.13 : double"
## [1] "2+3i : complex"
## [1] "Astrobiología : character"
## [1] "Bueno : integer" "Excelente : integer" "Regular : integer"
## [4] "Muy Bueno : integer"
## [1] "NA : character"
## [1] " : character"
Los valores son asignados a diferentes tipos de datos o variables, entre ellos se tiene a: vectores (vector), matrices (matrix), arreglos (array), tablas (data.frame), listas (lists).
El vector es una estructura fundamental en R y puede contener un solo tipo de dato, sea este integer, double, character, complex o raw. Un vector se crea con c(elementos del vector), donde c indica concatenar o combinar. Los vectores tienen una sola fila o una sola columna de valores.
digitos <- c(0, 1, 2, 3, 4, 5, 6, 7, 8, 9)
constantes <- c(0.2, 3.14, 2.718)
carreras_ikiam <- c("BTC", "ECO", "GEO", "H2O", "ARQ", "AGR", "BEC", "CEX")
sitios <- t(c("sitio1", "sitio2", "sitio3")) # transposeExplorar contenidos de vectores
Se puede hacer la exploración de los contenidos de los vectores con las siguientes órdenes:
# verificar el tipo de dato
class(digitos)## [1] "numeric"
# número de elementos del vector
length(digitos)## [1] 10
# escoger un solo elemento del vector
digitos[6]## [1] 5
# escoger todos excepto el primer elemento del vector
digitos[-1]## [1] 1 2 3 4 5 6 7 8 9
# escoger algunos elementos del vector
digitos[3:6]## [1] 2 3 4 5
# Operar con escalares
digitos*3 + 2## [1] 2 5 8 11 14 17 20 23 26 29
sqrt(digitos-1)## [1] NaN 0.000000 1.000000 1.414214 1.732051 2.000000 2.236068 2.449490
## [9] 2.645751 2.828427
digitos/constantes## [1] 0.0000000 0.3184713 0.7358352 15.0000000 1.2738854 1.8395879
## [7] 30.0000000 2.2292994 2.9433407 45.0000000
digitos*constantes## [1] 0.000 3.140 5.436 0.600 12.560 13.590 1.200 21.980 21.744 1.800
Una alternativa de crear vectores es generando sequencias seq() o replicate()
secuencia0 <- 1:6
secuencia1 <- seq(from=0, to= 20, by = 0.5)
secuencia1 <- seq(0, 20, by = 0.5)
secuencia1 <- seq(0, 20, length = 40)
secuencia2 <- replicate(10, 0)
secuencia3 <- replicate(10, 3)Una matriz es una estructura bidimensional, que contiene m número de filas (horizontal) y n número de columnas (vertical).
# Transformar un vector a matriz
vector1 <- 1:30
dim(vector1) <- c(6, 5)
class(vector1)## [1] "matrix" "array"
# Crear una matriz con matrix()
matriz2 <- matrix(2:41, 8,5)
matriz2## [,1] [,2] [,3] [,4] [,5]
## [1,] 2 10 18 26 34
## [2,] 3 11 19 27 35
## [3,] 4 12 20 28 36
## [4,] 5 13 21 29 37
## [5,] 6 14 22 30 38
## [6,] 7 15 23 31 39
## [7,] 8 16 24 32 40
## [8,] 9 17 25 33 41
# Crear una matriz uniendo vectores como columna
ciudad <- c("Quito", "Guayaquil", "Cuenca", "Ambato")
poblacion <- c(2.87, 2.98, 0.55, 0.32) # millones de personas
altura <- c(2765, 6, 2567, 2382) # sobre el nivel del mar
datos_ciudad <- cbind(ciudad, poblacion, altura)
datos_ciudad## ciudad poblacion altura
## [1,] "Quito" "2.87" "2765"
## [2,] "Guayaquil" "2.98" "6"
## [3,] "Cuenca" "0.55" "2567"
## [4,] "Ambato" "0.32" "2382"
# Crear una matriz uniendo vectores como filas
especie1 <- c("Sp1", 3, "terrestre")
especie2 <- c("Sp2", 1, "acuatico")
especie3 <- c("Sp3", 5, "terrestre")
especie4 <- c("Sp4", 2, "terrestre")
especie5 <- c("Sp5", 1, "marino")
diversidad <- rbind(especie1, especie2, especie3, especie4, especie5)
diversidad## [,1] [,2] [,3]
## especie1 "Sp1" "3" "terrestre"
## especie2 "Sp2" "1" "acuatico"
## especie3 "Sp3" "5" "terrestre"
## especie4 "Sp4" "2" "terrestre"
## especie5 "Sp5" "1" "marino"
Explorar contenidos de matrices
Se puede hacer la exploración de los contenidos de los matrices con las siguientes órdenes:
# verificar el tipo de dato
class(datos_ciudad)## [1] "matrix" "array"
# número de elementos de la matriz
dim(datos_ciudad)## [1] 4 3
# escoger un solo elemento de la matriz
datos_ciudad[2,1] # elemento de la fila 2 y columna 1## ciudad
## "Guayaquil"
# escoger una fila completa
datos_ciudad[1,]## ciudad poblacion altura
## "Quito" "2.87" "2765"
# escoger una columna completa
datos_ciudad[,3]## [1] "2765" "6" "2567" "2382"
# escoger determinadas filas y columnas
datos_ciudad[2:4,1:2]## ciudad poblacion
## [1,] "Guayaquil" "2.98"
## [2,] "Cuenca" "0.55"
## [3,] "Ambato" "0.32"
# renombrar columnas
diversidad## [,1] [,2] [,3]
## especie1 "Sp1" "3" "terrestre"
## especie2 "Sp2" "1" "acuatico"
## especie3 "Sp3" "5" "terrestre"
## especie4 "Sp4" "2" "terrestre"
## especie5 "Sp5" "1" "marino"
colnames(diversidad)## NULL
colnames(diversidad) <- c("Especie", "Crias","Habitat" )
diversidad## Especie Crias Habitat
## especie1 "Sp1" "3" "terrestre"
## especie2 "Sp2" "1" "acuatico"
## especie3 "Sp3" "5" "terrestre"
## especie4 "Sp4" "2" "terrestre"
## especie5 "Sp5" "1" "marino"
rownames(diversidad)## [1] "especie1" "especie2" "especie3" "especie4" "especie5"
LOs arreglos son estructuras rectangulares multidimensionales para guardar datos. Las matrices son arreglos de dos dimensiones. Se generan con array()
arreglo1 <- array(1:24, dim = c(3 , 2, 4))
arreglo1## , , 1
##
## [,1] [,2]
## [1,] 1 4
## [2,] 2 5
## [3,] 3 6
##
## , , 2
##
## [,1] [,2]
## [1,] 7 10
## [2,] 8 11
## [3,] 9 12
##
## , , 3
##
## [,1] [,2]
## [1,] 13 16
## [2,] 14 17
## [3,] 15 18
##
## , , 4
##
## [,1] [,2]
## [1,] 19 22
## [2,] 20 23
## [3,] 21 24
dimnames(arreglo1)## NULL
# cambiar nombres del arreglo 1
dimnames(arreglo1) <- list(c("fila1", "fila2", "fila3"),
c("col1", "col2"),
c("fondo1", "fondo2", "fondo3", "fondo4"))
dimnames(arreglo1)## [[1]]
## [1] "fila1" "fila2" "fila3"
##
## [[2]]
## [1] "col1" "col2"
##
## [[3]]
## [1] "fondo1" "fondo2" "fondo3" "fondo4"
Explorar la información de un arreglo
arreglo1[, , 1]## col1 col2
## fila1 1 4
## fila2 2 5
## fila3 3 6
arreglo1[, 1, ]## fondo1 fondo2 fondo3 fondo4
## fila1 1 7 13 19
## fila2 2 8 14 20
## fila3 3 9 15 21
Un data frame es una estructura de datos bidimensional similar a una matriz, sin embargo es una tabla simple formado por una lista de vectores de la misma longitud. Un Data frame se diferencia de una matriz en que la primera puede contener tipos de datos mixtos (numérico, lógico, caracter), mientras que el segundo tiene generalmente datos numéricos. Una dataframe se crea con data.frame(elementos)
calificaciones = data.frame(estudiante = paste0("Est", 1:20), calificacion = sample(0:10, 20, replace = TRUE))
calificaciones## estudiante calificacion
## 1 Est1 4
## 2 Est2 4
## 3 Est3 6
## 4 Est4 5
## 5 Est5 0
## 6 Est6 7
## 7 Est7 3
## 8 Est8 7
## 9 Est9 5
## 10 Est10 6
## 11 Est11 0
## 12 Est12 4
## 13 Est13 10
## 14 Est14 3
## 15 Est15 5
## 16 Est16 9
## 17 Est17 3
## 18 Est18 9
## 19 Est19 10
## 20 Est20 7
Explorar los elementos de data frame
Se puede utilizar df$columna para identificar una columna o tambien df["columna"]
# Seleccionar datos de una columna
calificaciones$calificacion## [1] 4 4 6 5 0 7 3 7 5 6 0 4 10 3 5 9 3 9 10 7
# Seleccionar datos de una columna
calificaciones["estudiante"]## estudiante
## 1 Est1
## 2 Est2
## 3 Est3
## 4 Est4
## 5 Est5
## 6 Est6
## 7 Est7
## 8 Est8
## 9 Est9
## 10 Est10
## 11 Est11
## 12 Est12
## 13 Est13
## 14 Est14
## 15 Est15
## 16 Est16
## 17 Est17
## 18 Est18
## 19 Est19
## 20 Est20
# Crear una nueva columna
calificaciones$Criterio = ""
calificaciones["Nacionalidad"] = sample(c("Ecuatoriana", "Extranjera"),
20, replace=TRUE)
etnia = c("Indígena", "Afro", "Mestizo", "Blanco", "Otro")
etnias <- sample(etnia, 20, replace=TRUE)
calificaciones$Etnia = etnias
# Identificar los nombres de columnas
colnames(calificaciones)## [1] "estudiante" "calificacion" "Criterio" "Nacionalidad" "Etnia"
# Selección o subconjunto df[filas, columnas]
calificaciones[5:10, 1:4]## estudiante calificacion Criterio Nacionalidad
## 5 Est5 0 Extranjera
## 6 Est6 7 Extranjera
## 7 Est7 3 Extranjera
## 8 Est8 7 Extranjera
## 9 Est9 5 Extranjera
## 10 Est10 6 Extranjera
# Selección o subconjunto con un criterio
cal_ecuatoriana <- subset(calificaciones, Nacionalidad == "Ecuatoriana")
cal_ecuatoriana## estudiante calificacion Criterio Nacionalidad Etnia
## 2 Est2 4 Ecuatoriana Otro
## 13 Est13 10 Ecuatoriana Indígena
## 18 Est18 9 Ecuatoriana Otro
## 19 Est19 10 Ecuatoriana Otro
# Selección o subconjunto multicriterio
ecu_aprobados <- subset(calificaciones,
Nacionalidad == "Ecuatoriana" & calificacion >= 6)
ecu_aprobados## estudiante calificacion Criterio Nacionalidad Etnia
## 13 Est13 10 Ecuatoriana Indígena
## 18 Est18 9 Ecuatoriana Otro
## 19 Est19 10 Ecuatoriana Otro
# Visualizar las primeras filas
head(calificaciones, 3)## estudiante calificacion Criterio Nacionalidad Etnia
## 1 Est1 4 Extranjera Otro
## 2 Est2 4 Ecuatoriana Otro
## 3 Est3 6 Extranjera Indígena
# Visualizar las últimas filas
tail(calificaciones, 3)## estudiante calificacion Criterio Nacionalidad Etnia
## 18 Est18 9 Ecuatoriana Otro
## 19 Est19 10 Ecuatoriana Otro
## 20 Est20 7 Extranjera Blanco
Una lista es una colección de elementos que pueden ser de diferente tipo. Los componentes de una lista contienen una clave y el respectivo valor. Una lista se crea con list().
listado <- list(
"digitos"= digitos,
"diversidad" = diversidad,
"arreglo1" = arreglo1,
"elementos" = 3,
"palabras" = c("estrellas", "planetas", "sateĺites"),
"calificaciones" = calificaciones)
listado## $digitos
## [1] 0 1 2 3 4 5 6 7 8 9
##
## $diversidad
## Especie Crias Habitat
## especie1 "Sp1" "3" "terrestre"
## especie2 "Sp2" "1" "acuatico"
## especie3 "Sp3" "5" "terrestre"
## especie4 "Sp4" "2" "terrestre"
## especie5 "Sp5" "1" "marino"
##
## $arreglo1
## , , fondo1
##
## col1 col2
## fila1 1 4
## fila2 2 5
## fila3 3 6
##
## , , fondo2
##
## col1 col2
## fila1 7 10
## fila2 8 11
## fila3 9 12
##
## , , fondo3
##
## col1 col2
## fila1 13 16
## fila2 14 17
## fila3 15 18
##
## , , fondo4
##
## col1 col2
## fila1 19 22
## fila2 20 23
## fila3 21 24
##
##
## $elementos
## [1] 3
##
## $palabras
## [1] "estrellas" "planetas" "satelites"
##
## $calificaciones
## estudiante calificacion Criterio Nacionalidad Etnia
## 1 Est1 4 Extranjera Otro
## 2 Est2 4 Ecuatoriana Otro
## 3 Est3 6 Extranjera Indígena
## 4 Est4 5 Extranjera Blanco
## 5 Est5 0 Extranjera Afro
## 6 Est6 7 Extranjera Afro
## 7 Est7 3 Extranjera Mestizo
## 8 Est8 7 Extranjera Mestizo
## 9 Est9 5 Extranjera Otro
## 10 Est10 6 Extranjera Afro
## 11 Est11 0 Extranjera Mestizo
## 12 Est12 4 Extranjera Mestizo
## 13 Est13 10 Ecuatoriana Indígena
## 14 Est14 3 Extranjera Afro
## 15 Est15 5 Extranjera Afro
## [ reached 'max' / getOption("max.print") -- omitted 5 rows ]
Explorar los elementos de las listas
Se puede utilizar lista$elemento o tambien un doble corchete lista[[indice]]
# uno de los elementos de la lista
listado$elementos # cuarto elemento de la lista## [1] 3
listado$diversidad # segundo elemento de la lista## Especie Crias Habitat
## especie1 "Sp1" "3" "terrestre"
## especie2 "Sp2" "1" "acuatico"
## especie3 "Sp3" "5" "terrestre"
## especie4 "Sp4" "2" "terrestre"
## especie5 "Sp5" "1" "marino"
listado[[2]] # segundo elemento de la lista## Especie Crias Habitat
## especie1 "Sp1" "3" "terrestre"
## especie2 "Sp2" "1" "acuatico"
## especie3 "Sp3" "5" "terrestre"
## especie4 "Sp4" "2" "terrestre"
## especie5 "Sp5" "1" "marino"
listado[[2]][1,] # fila 1 del segundo elemento de la lista## Especie Crias Habitat
## "Sp1" "3" "terrestre"
R tiene conjuntos de datos tabulados (datasets) que se incluyen por defecto en la instalación de R. Para enlistar los datasets de R se requiere la orden data(). Para cargar uno de los datasets solo se debe escribir el nombre y asignar a un identificador.
data()
# Selección del dataset "iris"
?iris
head(iris, 4)## Sepal.Length Sepal.Width Petal.Length Petal.Width Species
## 1 5.1 3.5 1.4 0.2 setosa
## 2 4.9 3.0 1.4 0.2 setosa
## 3 4.7 3.2 1.3 0.2 setosa
## 4 4.6 3.1 1.5 0.2 setosa
str(iris) # Estructura del dataset## 'data.frame': 150 obs. of 5 variables:
## $ Sepal.Length: num 5.1 4.9 4.7 4.6 5 5.4 4.6 5 4.4 4.9 ...
## $ Sepal.Width : num 3.5 3 3.2 3.1 3.6 3.9 3.4 3.4 2.9 3.1 ...
## $ Petal.Length: num 1.4 1.4 1.3 1.5 1.4 1.7 1.4 1.5 1.4 1.5 ...
## $ Petal.Width : num 0.2 0.2 0.2 0.2 0.2 0.4 0.3 0.2 0.2 0.1 ...
## $ Species : Factor w/ 3 levels "setosa","versicolor",..: 1 1 1 1 1 1 1 1 1 1 ...
# Selección del dataset "ChickWeight"
?ChickWeight
colnames(ChickWeight)## [1] "weight" "Time" "Chick" "Diet"
head(ChickWeight, 4)## weight Time Chick Diet
## 1 42 0 1 1
## 2 51 2 1 1
## 3 59 4 1 1
## 4 64 6 1 1
str(ChickWeight) # Estructura del dataset## Classes 'nfnGroupedData', 'nfGroupedData', 'groupedData' and 'data.frame': 578 obs. of 4 variables:
## $ weight: num 42 51 59 64 76 93 106 125 149 171 ...
## $ Time : num 0 2 4 6 8 10 12 14 16 18 ...
## $ Chick : Ord.factor w/ 50 levels "18"<"16"<"15"<..: 15 15 15 15 15 15 15 15 15 15 ...
## $ Diet : Factor w/ 4 levels "1","2","3","4": 1 1 1 1 1 1 1 1 1 1 ...
## - attr(*, "formula")=Class 'formula' language weight ~ Time | Chick
## .. ..- attr(*, ".Environment")=<environment: R_EmptyEnv>
## - attr(*, "outer")=Class 'formula' language ~Diet
## .. ..- attr(*, ".Environment")=<environment: R_EmptyEnv>
## - attr(*, "labels")=List of 2
## ..$ x: chr "Time"
## ..$ y: chr "Body weight"
## - attr(*, "units")=List of 2
## ..$ x: chr "(days)"
## ..$ y: chr "(gm)"
chicken_diet2 <- ChickWeight[ChickWeight$Diet == "2",]
# Extraer mulltiple datasets
ds <- c("USArrests", "VADeaths")
data(list = ds)Realice las siguientes actividades en un documento .Rmd
# Crear un identificador de nombre "ciudad" y asigne
# como valor el nombre de alguna ciudad
# Crear un identificador de nombre "pais_andes" y asigne como valor
# los nombres de los países por donde cruza la cordillera de Los Andes
# Crear un dataframe con 12 eventos (files) y 5 variables (columnas),
# cada columna debe tener diferentes tipos de datos (entero, decimal,
# caracter, logico)
# Cargue el dataset "DNase" e identifique su estructura. Extraiga (subset)
# los datos que cumplan con las condiciones de:
# 1. "conc" (concentracion) entre 0.1 y 0.2
# 2. "Run" diferente a 2, "conc" mayor a 0.2 y "density" menor o igual a 1.0Items de cada componente de la interfaz de RStudio: http://wpd.ugr.es/~bioestad/guia-r-studio/practica-1-r-studio/
Textos de R: https://rstudio.com/resources/books/
Guías rápidas (Cheatsheets) de algunos paquetes de R, disponibles en: https://github.com/rstudio/cheatsheets
Son instrucciones que permiten controlar el flujo de ejecución de los comandos. Estas estrucuturas posibilitan asignar operaciones lógicas en el código. Además las estructuras de control permiten reutilizar fragmentos de código una y otra vez.
ifLa estrucutura condicional if relaciona el cumplimiento de una condición y luego emite una conclusión.
if SimpleLa forma simple del condicional if emite una conclusión (mensaje o resultado) si la condición es verdadera; si es falso no se emite mensaje alguno.
if (condición) {
ejecutar orden si es verdadera la condición
}
knitr::include_graphics('./img/ifSimple.png')FIGURA 1: Estructura del condicional if simple
# Ejemplo de condicional simple
edad <- 20
if(edad >=18){
mensaje <- paste("El estudiante es mayor de edad, dado que tiene", edad, "años.")
print(mensaje)
}## [1] "El estudiante es mayor de edad, dado que tiene 20 años."
Si la edad <- 12, entonces ningún resultado se visualiza del código anterior; por lo que se requiere completar el código para que visualice otra leyenda cuando no se cumple la condición dada.
if - elseLa forma condicional if - else es la secuencia si cumple - entonces mensaje1 - sino mensaje2). Por ejemplo, si (if) una persona cumple con la condición de tener más de 18 años, entonces (then) se puede decir que es mayor de edad, sino (else) es menor de edad. El modelo para un if es el siguiente:
if (condición) {
ejecutar orden cuando es verdadero la condición
}else{
ejecutar orden cuando es falsa la condición
}
knitr::include_graphics('./img/ifelse.png')FIGURA 2: Estructura del condicional if - else
edad <- 12
if(edad >=18){
print(paste("El estudiante es mayor de edad, dado que tiene", edad, "años."))
}else{
print(paste("El estudiante es menor de edad, dado que tiene", edad, "años."))
}## [1] "El estudiante es menor de edad, dado que tiene 12 años."
edad <- 21
if(edad >=18){
print(paste("El estudiante es mayor de edad, dado que tiene", edad, "años."))
}else{
print(paste("El estudiante es menor de edad, dado que tiene", edad, "años."))
}## [1] "El estudiante es mayor de edad, dado que tiene 21 años."
Asignar un valor numérico a la variable altura. Si el valor de la altura es mayor o igual a 1200 (medidos en metros sobre el nivel del mar) debe desplegar la leyenda: Estás en la Sierra porque te encuentras a "valor" m.s.n.m. o en su defecto debe decir No estás en la Sierra porque te encuentras a "valor" m.s.n.m
# Crea tu variable "altura"
# Escribe el condicionalif - else if - elseLa forma condicional if - else if - else es la secuencia
si1 cumple - entonces mensaje1 -- si2 - entonces mensaje2 -- si_n ... - sino mensaje3),
se puede utilizar varios else if en el código. Por ejemplo, si (if) un animal se alimenta exclusivamente de vegetales, entonces es un herbíboro, si (else if) se alimenta exclusivamente de carne, entonces es un carnívoro; si (else if) se alimenta de insectos entonces es un insectivoro; sino (else) se podría decir que es un omnívoro. El modelo para un if - else if - else es el siguiente:
if (condición) {
ejecutar orden cuando es verdadero la condición 1
}elif{
ejecutar orden cuando es verdadero la condición 2
}else{
ejecutar orden cuando las condiciones 1 y 2 son falsas
}
knitr::include_graphics('./img/elif.png')FIGURA 3: Estructura del condicional if - else if - else
dieta <- "carne"
if(dieta =="hierba"){
print(paste("El animal es herbivoro, porque su dieta se basa en ", dieta, "."))
}else if(dieta =="carne"){
print(paste("El animal es carnívoro, porque su dieta se basa en ", dieta, "."))
}else if (dieta == "insectos"){
print(paste("El animal es insectívoro, porque su dieta se basa en ", dieta, "."))
}else{
print(paste("El animal es omnívoro, porque su dieta se basa en ", dieta, "."))
}## [1] "El animal es carnívoro, porque su dieta se basa en carne ."
edad <- 21
if(edad >=18){
print(paste("El estudiante es mayor de edad, dado que tiene", edad, "años."))
}else{
print(paste("El estudiante es menor de edad, dado que tiene", edad, "años."))
}## [1] "El estudiante es mayor de edad, dado que tiene 21 años."
Se puede concantenar dos o más condiciones en un if utilizando operadores lógico (y: &, o: | o no: ! ).
# Condiciones para aprobar la materia
estudiante <- "Vidal Carlos"
asistencia <- 40 # como porcentaje
promedio <- 6.2 # calificación sobre 10 puntos
# Condicional
if(asistencia >= 70 & promedio >= 6.0){
print(paste(toupper(estudiante),"| Promedio: ", promedio, "| Asistencia: ", asistencia, "| APROBADO"))
}else{
print(paste(toupper(estudiante),"| Promedio: ", promedio, "| Asistencia: ", asistencia, "| REPROBADO"))
}## [1] "VIDAL CARLOS | Promedio: 6.2 | Asistencia: 40 | REPROBADO"
# Opciones en protocolo
organismo <- "Zea mays" # maíz, "Theobroma cacao" (cacao), "Manihot esculenta" (yuca)
concentracion <- 1 # medidos en ug/mml
# Condicional
if((organismo == "Zea mays" | organismo == "Theobroma cacao")& concentracion >= 5.0){
print(paste(organismo,"| Concentración: ", concentracion, "| Protocolo 1"))
}else if((organismo == "Manihot esculenta")& concentracion >= 5.0){
print(paste(organismo,"| Concentración: ", concentracion, "| Protocolo 2"))
}else{
print(paste(organismo,"| Concentración: ", concentracion, "| Protocolo 3"))
}## [1] "Zea mays | Concentración: 1 | Protocolo 3"
Se puede imprimir un una sola línea la condicional simple de if, con la siguiente orden:
if(condición) SiVerdad.
# Disminuya la velocidad
velocidad <- 120
if(velocidad > 90) print("Disminuya su velocidad")## [1] "Disminuya su velocidad"
Se puede aplicar la condicional if - else para un valor simple en una sola línea con la siguiente orden:
if(condición) SiVerdad else SiFalso.
nota <- 5
if(nota>=6) "Aprobado" else "Reprobado"## [1] "Reprobado"
Se puede aplicar la condicional if - else para un vector, en una sola línea con la siguiente orden:
ifelse(condición, SiVerdad, SiFalso).
notas <- c(6,4,5,7,9.7,2.5)
ifelse(notas>=6, "Aprobado", "Reprobado")## [1] "Aprobado" "Reprobado" "Reprobado" "Aprobado" "Aprobado" "Reprobado"
if anidadoSe puede utilizar la condicional if dentro de otra condicional if, a esto se denomina if anidado.
knitr::include_graphics('./img/nestedif.webp')FIGURA 4: Estructura del condicional if anidado
set.seed(123) # semilla que hace replicable el resultado
aspirantes <- data.frame(Aspirante = paste("Aspirante",seq(1,20,by=2)),
Edad = sample(15:30,10,FALSE),
Talla = sample(100:200,10,FALSE),
TipoSangre = sample(c("A", "B", "O"),10,TRUE),
Instruccion = sample(c("Primaria", "Secundaria", "TercerNivel", "CuartoNivel"),10,TRUE))
aspirantes## Aspirante Edad Talla TipoSangre Instruccion
## 1 Aspirante 1 29 124 B Primaria
## 2 Aspirante 3 30 189 O CuartoNivel
## 3 Aspirante 5 17 190 B TercerNivel
## 4 Aspirante 7 28 168 A CuartoNivel
## 5 Aspirante 9 24 198 B Secundaria
## 6 Aspirante 11 16 156 O Primaria
## 7 Aspirante 13 20 191 B TercerNivel
## 8 Aspirante 15 19 108 A Primaria
## 9 Aspirante 17 18 192 O Primaria
## 10 Aspirante 19 26 171 O Secundaria
# if simple
aspirantes$Acceso = ifelse(aspirantes$Talla>150,"Aceptado","Rechazado")
aspirantes## Aspirante Edad Talla TipoSangre Instruccion Acceso
## 1 Aspirante 1 29 124 B Primaria Rechazado
## 2 Aspirante 3 30 189 O CuartoNivel Aceptado
## 3 Aspirante 5 17 190 B TercerNivel Aceptado
## 4 Aspirante 7 28 168 A CuartoNivel Aceptado
## 5 Aspirante 9 24 198 B Secundaria Aceptado
## 6 Aspirante 11 16 156 O Primaria Aceptado
## 7 Aspirante 13 20 191 B TercerNivel Aceptado
## 8 Aspirante 15 19 108 A Primaria Rechazado
## 9 Aspirante 17 18 192 O Primaria Aceptado
## 10 Aspirante 19 26 171 O Secundaria Aceptado
aspirantes$Acceso = NULL
aspirantes## Aspirante Edad Talla TipoSangre Instruccion
## 1 Aspirante 1 29 124 B Primaria
## 2 Aspirante 3 30 189 O CuartoNivel
## 3 Aspirante 5 17 190 B TercerNivel
## 4 Aspirante 7 28 168 A CuartoNivel
## 5 Aspirante 9 24 198 B Secundaria
## 6 Aspirante 11 16 156 O Primaria
## 7 Aspirante 13 20 191 B TercerNivel
## 8 Aspirante 15 19 108 A Primaria
## 9 Aspirante 17 18 192 O Primaria
## 10 Aspirante 19 26 171 O Secundaria
# if anidado
# Supongamos que el primer criterio para aceptar es la talla: apto: 20 puntos, no apto: 0 puntos
# El segundo criterio es la instrucción: tercernivel y cuartonivel: 20 puntos, otros: 0 puntos
# El tecer criterio es la Edad: 18-30 años: 10 puntos, otras edades: 0 puntos
aspirantes$Puntaje <- ifelse(aspirantes$Talla >= 150 & aspirantes$Instruccion %in% c("TercerNivel","CuartoNivel") & aspirantes$Edad %in% 18:30, 50,
ifelse(aspirantes$Talla >= 150 & aspirantes$Edad %in% 18:30, 40,
ifelse(aspirantes$Talla >= 150, 20, 0)))
aspirantes## Aspirante Edad Talla TipoSangre Instruccion Puntaje
## 1 Aspirante 1 29 124 B Primaria 0
## 2 Aspirante 3 30 189 O CuartoNivel 50
## 3 Aspirante 5 17 190 B TercerNivel 20
## 4 Aspirante 7 28 168 A CuartoNivel 50
## 5 Aspirante 9 24 198 B Secundaria 40
## 6 Aspirante 11 16 156 O Primaria 20
## 7 Aspirante 13 20 191 B TercerNivel 50
## 8 Aspirante 15 19 108 A Primaria 0
## 9 Aspirante 17 18 192 O Primaria 40
## 10 Aspirante 19 26 171 O Secundaria 40
aspirantes$Acceso <- ifelse(aspirantes$Puntaje >= 40, "Pruebas Psicométricas", "Siga Participando")
aspirantes## Aspirante Edad Talla TipoSangre Instruccion Puntaje Acceso
## 1 Aspirante 1 29 124 B Primaria 0 Siga Participando
## 2 Aspirante 3 30 189 O CuartoNivel 50 Pruebas Psicométricas
## 3 Aspirante 5 17 190 B TercerNivel 20 Siga Participando
## 4 Aspirante 7 28 168 A CuartoNivel 50 Pruebas Psicométricas
## 5 Aspirante 9 24 198 B Secundaria 40 Pruebas Psicométricas
## 6 Aspirante 11 16 156 O Primaria 20 Siga Participando
## 7 Aspirante 13 20 191 B TercerNivel 50 Pruebas Psicométricas
## 8 Aspirante 15 19 108 A Primaria 0 Siga Participando
## 9 Aspirante 17 18 192 O Primaria 40 Pruebas Psicométricas
## 10 Aspirante 19 26 171 O Secundaria 40 Pruebas Psicométricas
whileEl bucle while se utiliza cuando se desea correr indefinidamente una orden hasta que la condición sea encontrada. El siguiente es la estructura del bucle while():
while(condición){
ejecutar repedtidamente la orden
pasos de la variable
}
knitr::include_graphics('./img/while.png')FIGURA 5: Estructura del bucle while
En el bucle while, los valores Zero, None, Null , vacío (empty) se considera que corresponden a una condición FALSE; mientras que cualquier otro valor se considera TRUE.
x <-4
while (x) {
print(x)
x <- x-1 # siempre se requiere definir el paso
} ## [1] 4
## [1] 3
## [1] 2
## [1] 1
x <- -4
while (x) {
print(x)
x <- x+1 # siempre se requiere definir el paso
} ## [1] -4
## [1] -3
## [1] -2
## [1] -1
El siguiente código no devuelve resultado alguno, porque él valor de la variable corresponde a FALSE.
x <- 0
while (x) {
print(x)
x <- x+1 # siempre se requiere definir el paso
} while con breakEn ocasiones se requiere que al cumplir alguna condición, se pare la orden por completo, para ello se utiliza la función break.
while(condición){
Ejecutar orden
Paso
if(condición2) break
}
nota <- 10
while(nota){
print(paste("Nota:", nota))
nota <- nota - 1
if(nota < 6)
break
}## [1] "Nota: 10"
## [1] "Nota: 9"
## [1] "Nota: 8"
## [1] "Nota: 7"
## [1] "Nota: 6"
while con nextEn ocasiones se requiere que al cumplir alguna condición, se salte la orden, para ello se utiliza la función next.
while(condición){
Paso
if(condición2) next
Ejecutar orden
}
nota <- 10
while(nota){
nota <- nota - 1
if(nota == 6)
next
print(paste("Nota:", nota))
}## [1] "Nota: 9"
## [1] "Nota: 8"
## [1] "Nota: 7"
## [1] "Nota: 5"
## [1] "Nota: 4"
## [1] "Nota: 3"
## [1] "Nota: 2"
## [1] "Nota: 1"
## [1] "Nota: 0"
forEl bucle for o for loop es una función que permite iterar sobre cada elemento de un vector o una lista. La estructura del bucle for es la siguiente:
for(condición iterable){
ejecutar repetidamente la orden
}
knitr::include_graphics('./img/for.png')FIGURA 6: Estructura del bucle for
# bucle for en un vector
colores <- c("verde", "azul", "rojo")
for(color in colores){
print(color)
}## [1] "verde"
## [1] "azul"
## [1] "rojo"
# bucle for en un dataframe
str(iris)## 'data.frame': 150 obs. of 5 variables:
## $ Sepal.Length: num 5.1 4.9 4.7 4.6 5 5.4 4.6 5 4.4 4.9 ...
## $ Sepal.Width : num 3.5 3 3.2 3.1 3.6 3.9 3.4 3.4 2.9 3.1 ...
## $ Petal.Length: num 1.4 1.4 1.3 1.5 1.4 1.7 1.4 1.5 1.4 1.5 ...
## $ Petal.Width : num 0.2 0.2 0.2 0.2 0.2 0.4 0.3 0.2 0.2 0.1 ...
## $ Species : Factor w/ 3 levels "setosa","versicolor",..: 1 1 1 1 1 1 1 1 1 1 ...
for (especie in unique(iris$Species)){
data <- iris[iris$Species== especie,]
print(paste(especie, length(data$Species)))
}## [1] "setosa 50"
## [1] "versicolor 50"
## [1] "virginica 50"
# bucle for en una lista dataframe
lista <- list("a", 5, 3.15, 2+3i, c(TRUE, FALSE, TRUE), iris, mtcars)
for (item in lista){
print(item)
}## [1] "a"
## [1] 5
## [1] 3.15
## [1] 2+3i
## [1] TRUE FALSE TRUE
## Sepal.Length Sepal.Width Petal.Length Petal.Width Species
## 1 5.1 3.5 1.4 0.2 setosa
## 2 4.9 3.0 1.4 0.2 setosa
## 3 4.7 3.2 1.3 0.2 setosa
## 4 4.6 3.1 1.5 0.2 setosa
## 5 5.0 3.6 1.4 0.2 setosa
## 6 5.4 3.9 1.7 0.4 setosa
## 7 4.6 3.4 1.4 0.3 setosa
## 8 5.0 3.4 1.5 0.2 setosa
## 9 4.4 2.9 1.4 0.2 setosa
## 10 4.9 3.1 1.5 0.1 setosa
## 11 5.4 3.7 1.5 0.2 setosa
## 12 4.8 3.4 1.6 0.2 setosa
## 13 4.8 3.0 1.4 0.1 setosa
## 14 4.3 3.0 1.1 0.1 setosa
## 15 5.8 4.0 1.2 0.2 setosa
## [ reached 'max' / getOption("max.print") -- omitted 135 rows ]
## mpg cyl disp hp drat wt qsec vs am gear carb
## Mazda RX4 21.0 6 160 110 3.90 2.620 16.46 0 1 4 4
## Mazda RX4 Wag 21.0 6 160 110 3.90 2.875 17.02 0 1 4 4
## Datsun 710 22.8 4 108 93 3.85 2.320 18.61 1 1 4 1
## Hornet 4 Drive 21.4 6 258 110 3.08 3.215 19.44 1 0 3 1
## Hornet Sportabout 18.7 8 360 175 3.15 3.440 17.02 0 0 3 2
## Valiant 18.1 6 225 105 2.76 3.460 20.22 1 0 3 1
## [ reached 'max' / getOption("max.print") -- omitted 26 rows ]
for en una secuenciaSe puede definir el número de veces que se requiere iterar, generando una secuencia.
# Definir las veces que se itera
for (i in 1:8){
petal_area = iris$Petal.Length[i]*iris$Petal.Width[i]
print(paste("Area", i, ":", petal_area, "cm^2"))
}## [1] "Area 1 : 0.28 cm^2"
## [1] "Area 2 : 0.28 cm^2"
## [1] "Area 3 : 0.26 cm^2"
## [1] "Area 4 : 0.3 cm^2"
## [1] "Area 5 : 0.28 cm^2"
## [1] "Area 6 : 0.68 cm^2"
## [1] "Area 7 : 0.42 cm^2"
## [1] "Area 8 : 0.3 cm^2"
# Iterar en para todos los elementos del vector
sepal_areas <- c()
for (i in 1:length(iris$Sepal.Length)){
sepal_areas[i] = iris$Sepal.Length[i]*iris$Sepal.Width[i]
}
sepal_areas## [1] 17.85 14.70 15.04 14.26 18.00 21.06 15.64 17.00 12.76 15.19 19.98 16.32
## [13] 14.40 12.90 23.20 25.08 21.06 17.85 21.66 19.38 18.36 18.87 16.56 16.83
## [25] 16.32 15.00 17.00 18.20 17.68 15.04 14.88 18.36 21.32 23.10 15.19 16.00
## [37] 19.25 17.64 13.20 17.34 17.50 10.35 14.08 17.50 19.38 14.40 19.38 14.72
## [49] 19.61 16.50 22.40 20.48 21.39 12.65 18.20 15.96 20.79 11.76 19.14 14.04
## [61] 10.00 17.70 13.20 17.69 16.24 20.77 16.80 15.66 13.64 14.00 18.88 17.08
## [73] 15.75 17.08 18.56
## [ reached getOption("max.print") -- omitted 75 entries ]
# alternativa rápida
df <- iris
df$Sepal_area <- df$Sepal.Length*df$Sepal.Width
head(df, 4)## Sepal.Length Sepal.Width Petal.Length Petal.Width Species Sepal_area
## 1 5.1 3.5 1.4 0.2 setosa 17.85
## 2 4.9 3.0 1.4 0.2 setosa 14.70
## 3 4.7 3.2 1.3 0.2 setosa 15.04
## 4 4.6 3.1 1.5 0.2 setosa 14.26
for con breakLa orden break detiene al bucle y sale por completo de ella.
elementos <- c("H", "He", "Li", "Be", "B", "C", "N", "O", "F", "Ne", "Na", "Mg")
for (elem in elementos){
if (startsWith(elem,"N"))
break
print(elem)
}## [1] "H"
## [1] "He"
## [1] "Li"
## [1] "Be"
## [1] "B"
## [1] "C"
for con nextLa orden next salta al elemento que cumpla con el condicional y continua en el siguiente elemento del vector.
elementos <- c("H", "He", "Li", "Be", "B", "C", "N", "O", "F", "Ne", "Na", "Mg")
for (elem in elementos){
if (startsWith(elem,"N"))
next
print(elem)
}## [1] "H"
## [1] "He"
## [1] "Li"
## [1] "Be"
## [1] "B"
## [1] "C"
## [1] "O"
## [1] "F"
## [1] "Mg"
for (elem in elementos){
if (!startsWith(elem,"N"))
next
print(elem)
}## [1] "N"
## [1] "Ne"
## [1] "Na"
for anidadoCuandos se requiere que algo se repita para otro item que también se repite, se utiliza el for anidado.
# Se tiene 10 estaciones metereológicas y en cada una se desea medir: "Temperatura", "Precipitación", "Radiación", "VelocidadViento"
estaciones <- factor(1:10)
medidas <- factor(c("Temperatura", "Precipitación", "Radiación", "VelViento"))
# Imprimir en la consola
for(est in estaciones){
for(med in medidas){
print(paste(est, med))
}
}## [1] "1 Temperatura"
## [1] "1 Precipitación"
## [1] "1 Radiación"
## [1] "1 VelViento"
## [1] "2 Temperatura"
## [1] "2 Precipitación"
## [1] "2 Radiación"
## [1] "2 VelViento"
## [1] "3 Temperatura"
## [1] "3 Precipitación"
## [1] "3 Radiación"
## [1] "3 VelViento"
## [1] "4 Temperatura"
## [1] "4 Precipitación"
## [1] "4 Radiación"
## [1] "4 VelViento"
## [1] "5 Temperatura"
## [1] "5 Precipitación"
## [1] "5 Radiación"
## [1] "5 VelViento"
## [1] "6 Temperatura"
## [1] "6 Precipitación"
## [1] "6 Radiación"
## [1] "6 VelViento"
## [1] "7 Temperatura"
## [1] "7 Precipitación"
## [1] "7 Radiación"
## [1] "7 VelViento"
## [1] "8 Temperatura"
## [1] "8 Precipitación"
## [1] "8 Radiación"
## [1] "8 VelViento"
## [1] "9 Temperatura"
## [1] "9 Precipitación"
## [1] "9 Radiación"
## [1] "9 VelViento"
## [1] "10 Temperatura"
## [1] "10 Precipitación"
## [1] "10 Radiación"
## [1] "10 VelViento"
#_____________________________________
# Guardar en un dataframe
datos_met <- data.frame() # Dataframe vacío
for(i in 1:length(estaciones)){
for(j in 1:length(medidas)){
datos_met <- rbind(datos_met , c(estaciones[i], medidas[j]))
}
}
# cambiar nombres de columnas
names(datos_met) <- c("Estacion", "Medida")
# cambiar nombres de cada factor de la columna "Medida"
datos_met$Medida <- with(datos_met, ifelse(Medida==1, "Temperatura",
ifelse(Medida==2, "Precipitación",
ifelse(Medida==3, "Radiación", "VelViento"))))
str(datos_met)## 'data.frame': 40 obs. of 2 variables:
## $ Estacion: int 1 1 1 1 2 2 2 2 3 3 ...
## $ Medida : chr "VelViento" "VelViento" "VelViento" "VelViento" ...
Existen varias funciones pre-cargadas en R las cuales puede ser utilizadas a la vez para esscribir nuevas funciones.
Se tiene operaciones para las cuales no se tiene funciones definidas, por lo tanto deben ser escritas. Una función es un bloque de instrucciones que pueden ser utilizadas continuamente en un programa, es decir, permite automatizar operaciones. Generar funciones es más productivo que copiar y pegar las instrucciones cada vez que se necesita, por lo tanto tiene las siguientes ventajas:
Se asigna un identificador que permite reconocer lo que realiza la función.
Se requiere pocos cambios, en general solamente los argumentos.
Se evita errores accidentales que pueden ocurrir al copiar y pegar.
Se puede utilizar para escribir nuevas funciones.
Se tiene una forma compacta para operar.
Facilita el aprendizaje del lenguaje de programación.
La estructura de una función es la siguiente:
nombreFuncion <- function(argumento1, argumento2, ...){
instruciones
return(resultado)
}
Se requiere una función cuando se repite (copia y pega) una instrucción por más de tres veces. Como en el siguiente caso ejemplo, donde se busca calcular la reescalar un valor con la fórmula:
\[x_{i} = \dfrac{x-mean(x)}{sd(x)}\]
df <- data.frame(a = rnorm(10),
b = rnorm(10),
c = rnorm(10),
d = rnorm(10))
df$a <- (df$a - mean(df$a, na.rm = TRUE)) / (sd(df$a, na.rm = TRUE))
df$b <- (df$b - mean(df$b, na.rm = TRUE)) / (sd(df$a, na.rm = TRUE)) # error
df$c <- (df$c - mean(df$c, na.rm = TRUE)) / (sd(df$c, na.rm = TRUE))
df$d <- (df$d - mean(df$d, na.rm = TRUE)) / (sd(df$d, na.rm = TRUE))En este ejemplo, se repite una instrucción que podríamos optimizar generando una función. Antes de continuar vamos a revisar funciones con las cuales tenemos mayor familiaridad.
Se tiene muchas funciones que ya están predefinidas en R, aquí algunas de ellas:
| Tipo | Función | Descripción |
|---|---|---|
| Numérico | abs(x) |
Valor absoluto [ abs(-32.3)=32.3] |
sqrt(x) |
Raíz cuadrada [ sqrt(25)=5] |
|
ceiling(x) |
Entero superior [ ceiling(2.3)=3] |
|
floor(x) |
Entero inferior [ floor(2.3)=2] |
|
trunc(x) |
Truncar, es seleccionar solamente el valor entero [ trunc(2.3)=2] |
|
round(x, digits=n) |
Redondear [ round(2.33273427247, digits=4)=2.3327] |
|
signif(x, digits=n) |
Cifras significativas [ signif(2.33273427247, digits=4)=2.3327] |
|
cocs(x), sin(x), tan(x) |
Funciones trigonométricas [ cos(pi)=-1] |
|
log(x), lo10(x), log2(x), log(x, base) |
Logaritmos [ logb(81 , 3)=4] |
|
| Texto | substr(x, star=n1, stop=n2) |
Extraer o reemplazar un “subtexto” en un vector de exto,
|
grep(patrón, x ignore.case = FALSE, fixed=FALSE) |
Busca un patrón en un vector de textos y devuelve los índice donde encuentra el patrón.
|
|
sub(patrón, reemplazo, x, ignore.case =FALSE, fixed=FALSE) |
Busca un patrón en un texto y reemplaza.
|
|
strsplit(x, separador) |
Separa los caracteres de un texto con separador.
|
|
paste(x, sep="") |
Concatena elementos utilizando un separador.
|
|
toupper(x) |
Convierte un texto en mayúsculas
|
|
tolower(x) |
Convierte un texto en minúsculas
|
|
| Estadística | dnorm(x) |
Función de densidad normal |
pnorm(x) |
Probabilidad acumulativa normal de x | |
qnorm(x) |
Quantil normal | |
rnorm(n, m=0, sd =1) |
Desviación normal aleatorio n, con promedio m y desviación estándar sd. |
|
mean(x, trim=0, na.rm=FALSE) |
Promedio de un vector
|
|
sd(x) |
Calcula la desviación estandar de un conjunto de valores. | |
median(x) |
Calcula la media de un conjunto de valores. | |
range(x) |
Calcula el rango de un conjunto de valores. | |
quantile(x, prob) |
Calcula el quantil de un conjunto de valores, dad una probabilidad (entre 0 y 1). | |
sum(x) |
Calcula la suma de un conjunto de valores. | |
min(x) |
Calcula el valor mínimo de un conjunto de valores. | |
max(x) |
Calcula el valor máximo de un conjunto de valores. | |
| Otras funciones | seq(desde, hasta, paso) |
Genera un vector con una secuencia de números dados el valor inicial, el valor final y el “paso” que se define. |
rep(x, n) |
Genera un vector donde el valor x se repite por n veces. |
|
cut(x, n) |
Divide una variable continua x en factores de n niveles. |
Se tiene más funciones predeterminadas con las cuales se puede ir familiarizando a medida que se entrena en R.
A continuación se crea la función cuadrado, donde el único argumento es la variable x y el resultado es \[y = x^{2}\]
# Forma de operar extensa
x<- 1
y = x**2
y## [1] 1
x<- 2
y = x**2
y## [1] 4
x<- 3
y = x**2
y## [1] 9
# Forma de operar con una función
cuadrado <- function(x) {
y = x**2
return(y)
}
# Se evalúa la función para algún valor
cuadrado(2)## [1] 4
cuadrado(c(1,2,3,4,5,6,7,78,934))## [1] 1 4 9 16 25 36 49 6084 872356
cuadrado(seq(1,10,0.2))## [1] 1.00 1.44 1.96 2.56 3.24 4.00 4.84 5.76 6.76 7.84
## [11] 9.00 10.24 11.56 12.96 14.44 16.00 17.64 19.36 21.16 23.04
## [21] 25.00 27.04 29.16 31.36 33.64 36.00 38.44 40.96 43.56 46.24
## [31] 49.00 51.84 54.76 57.76 60.84 64.00 67.24 70.56 73.96 77.44
## [41] 81.00 84.64 88.36 92.16 96.04 100.00
cuadrado(1:23)## [1] 1 4 9 16 25 36 49 64 81 100 121 144 169 196 225 256 289 324 361
## [20] 400 441 484 529
# Forma corta de la función cuadrado
(function(x) x**2)(2) # Evalúa para el valor 2 la función x^2## [1] 4
# Otra forma corta
cuadrado2 <- function(x) x**2
cuadrado2(c(1,2,3,476))## [1] 1 4 9 226576
Cuando se crean las funciones se pueden predefinir los valores de los parámetros, es decir si no se coloca un valor, entonces tomará el valor predeterminado.
# función potencia
potencia <- function(x=2, y=1){
pot = x**y
return(pot)
}
# Argumentos sin valores asignados
potencia()## [1] 2
# Definiendo el valor para un argumento
potencia(x=3)## [1] 3
potencia(y=3)## [1] 8
# Definiendo valores para ambos argumentos
potencia(x=5, y=3)## [1] 125
potencia(5,3)## [1] 125
# Función potencia aplicado a vectores
potencia(x = c(1,2,3,4,5,6), y=4)## [1] 1 16 81 256 625 1296
Para aplicar la función reescalar, se requiere utilizar la fórmula previamente indicada
df <- data.frame(a = rnorm(10),
b = rnorm(10),
c = rnorm(10),
d = rnorm(10))
reescalar <- function(x){
y = (x-mean(x))/sd(x)
return(y)
}
reescalar(df$a)## [1] -0.88888972 0.23066859 0.34844408 0.02673298 0.73434356 1.65242608
## [7] -0.41613079 -1.89615825 0.80229191 -0.59372844
colnamesdf <- colnames(df)
for (i in 1:ncol(df)){
print(paste(colnamesdf[i], reescalar(df[,i])))
}## [1] "a -0.888889718407366" "a 0.23066858908586" "a 0.348444077465671"
## [4] "a 0.0267329838289855" "a 0.734343559198163" "a 1.65242608309094"
## [7] "a -0.416130787566984" "a -1.89615825206489" "a 0.802291908534712"
## [10] "a -0.593728443165099"
## [1] "b -0.984241042037496" "b 1.64309760265583" "b -0.365981895636257"
## [4] "b -1.80101481684937" "b 0.348627737436173" "b -0.14230953395186"
## [7] "b 0.0794829212523827" "b 0.661374415436023" "b -0.49766778191108"
## [10] "b 1.05863239360565"
## [1] "c -0.946610786038974" "c -0.0489412632651389" "c 1.19459944977299"
## [4] "c 0.119126623385072" "c -1.11800346859132" "c 1.27907037459783"
## [7] "c 1.02663619111243" "c 0.303149559691809" "c -0.200187170993866"
## [10] "c -1.60883950967083"
## [1] "d 1.04710534248116" "d -0.74833844176276" "d 1.80402784494377"
## [4] "d 1.20455311963976" "d -0.414541928672822" "d -1.13853885201906"
## [7] "d -0.849190851664753" "d 0.0364762646365098" "d -0.424605947230849"
## [10] "d -0.516946550350959"
Cuando se desea clasificar o agregar, se puede utilizar una función con estrucuturas de control.
aspirantes <- data.frame(Aspirante = paste("Aspirante",seq(1,20,by=2)),
Edad = sample(15:30,10,FALSE),
Talla = sample(100:200,10,FALSE),
TipoSangre = sample(c("A", "B", "O"),10,TRUE),
Instruccion = sample(c("Primaria", "Secundaria", "TercerNivel", "CuartoNivel"),10,TRUE)
)
item_promedio <- function(x) {
total <- 0
n <- length(x)
for (i in seq_along(x)) {
total <- total + x[i] / n
}
total
}
item_promedio(aspirantes$Edad)## [1] 22
Realice las siguientes actividades en un documento .Rmd
Asignar un valor numérico a la variable altura. Para escribir el código if - else if - else, considere las siguientes condiciones relacionadas a la altura medida en kilómetros sobre el nivel del mar:
Si la altura está entre 0 Km y 10 Km, que se imprima la leyenda “Estás en la Troposfera”,
Si la altura está entre 10 Km y 50 Km, que se imprima la leyenda “Estás en la Estratosfera”,
Si la altura está entre 50 Km y 85 Km, que se imprima la leyenda “Estás en la Mesosfera”,
Si la altura está entre 80 Km y 500 Km, que se imprima la leyenda “Estás en la Termosfera”,
Si la altura es mayor a los 500 Km, que se imprima la leyenda “Estás en la Exosfera”,
Si la altura es menor a 0 Km, que se imprima la leyenda “Escribe un valor positivo para la altura”,
# Crea tu variable "altura"
# Escribe el condicional para las capas de la atmósfera. Simule el diseño de la tabla donde guardará los resultados de un experimento, que consta de:
Organismos, tres tipos de especímenes, por ejemplo:
c(“aullador”, “chichico”, “araña”)
c(“polipéptido_a”, “polipéptido_b”, “polipéptido_c”)
c(“roca_a”, “roca_b”, “roca_c”)
Tratamientos, cuatro tipos de tratamientos a cada tipo de especimen, por ejemplo:
c(“dieta1”, “dieta2”, “dieta3”, “dieta4”)
c(“enzima1”, “enzima2”, “enzima3”, “enzima4”)
c(“aleacion1”, “aleacion2”, “aleacion3”, “aleacion4”)
Medidas, realizará 5 tipos de medidas, por ejemplo:
c(“altura”, “largo”, “masa”, “NroProgenie”, “nroSobrevivientes”)
c(“NroProteinas”, Estructura”, “TempDenaturacion”, “RutaMetabólica”, “PesoMolecular”)
c(“Composicion”, “Estructura”, “Resistencia”, “Dureza”, “Porosidad”)
Utilizando el bucle for, arme un dataframe que tenga las columnas “Especimen”, “Tratamiento” y “Medida”. El dataframe debe tener todas las combinaciones posibles de las tres columnas, por ende por lo menos 60 filas.
# Crea el dataframe vacío
# Crea las variables "Especimen", "Tratamiento" y "Medida" con sus respectivas opciones
# Escribe el código para generar el dataframe utilizando el bucle "for" anidado
# Si alguna columna tiene valores "factor", cambie por los "character()" que correspondaRealice las siguientes actividades en un documento .Rmd
# Asigne la data precargada de R "mtcars" a la variable "df_mtcars"
# Cree una función "contar_cyl" que cuente el número de veces que divida el número de carros que existe por tipo de "cyl"
# Genere una función que calcule las pendientes de los datos "mpg - hp" y guarde en la variable "pendiente_mpg.hp"R viene con múltiples funciones pre-definidos, asimismo tiene paquetes pre-instalados. Sin embargo se tiene procesamientos que requieren funcionalidades adicionales. Estas funciones se desarrollan y almancenan repositorio de R denominada CRAN (https://cloud.r-project.org/). Para revisar el paquete disponible debe dirigirse a la sección “Software/Packages”. Aquí encontrará un aproximado de 16395 paquetes.
Para cargar los paquetes que han sido previamente instalados se debe usar la instrucción library("nombre.paquete"):
# Para maniular datos, se requerirá "readr" y "tidyverse"
library("readr")
library("tidyverse")Para manipular datos el “superpaquete” con mayor uso en R es tidyverse, cada uno de los paquetes que contiene tidyverse sirve en las etapas de análisis de datos, como se muestra en la siguiente figura:
knitr::include_graphics('./img/tidyverse.png')FIGURA 1: Flujo de análisis de datos y paquetes de tidyverse utilizados en cada etapa
Para cargar archivos se recomienda primero definir el espacio de trabajo o working directory, para ello se requiere conocer en donde el directoriodonde se está trabajando.
# Conocer el directorio de trabajo
getwd()## [1] "D:/GDrive/IKIAM/CLASES/2021II/2021II_GBI6/2021II_Clases/2021II_R/2021II_4.1_IntroduccionR_TiposDatos"
Teniendo el directorio de trabajo definido, podemos empezar a cargar data.
# Guardar data precargada de R como un archivo csv
write.csv(mtcars, "data/df_mtcars.csv")
df_mtcars <- read_csv("data/df_mtcars.csv")
head(df_mtcars, 1)## # A tibble: 1 x 12
## ...1 mpg cyl disp hp drat wt qsec vs am gear carb
## <chr> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
## 1 Mazda RX4 21 6 160 110 3.9 2.62 16.5 0 1 4 4
# str(df_mtcars)# Guardar data de un website como un archivo csv
library (RCurl)
# Desde un archivo de github microbioma restauración
df2 <- read_tsv("https://raw.githubusercontent.com/geohouse/Plant-Microbiomes-in-Grassland-Restorations/master/taxonomicAttributionOfAMF_OTUs.tsv")
head(df2, 1)## # A tibble: 1 x 4
## OTU_num Genus_Attribution Using_maxAccepts10_Jan2017_USEARCH~ Attribution_fro~
## <dbl> <dbl> <chr> <chr>
## 1 1 289 Diversispora "98\tU"
# str(df2)
# Desde un archivo de github clima
df3 <- read_csv("https://raw.githubusercontent.com/afanick10/rogers-pass-snowfall/master/climate-daily.csv")
head(df3, 1)## # A tibble: 1 x 36
## x y STATION_NAME CLIMATE_IDENTIFI~ ID LOCAL_DATE
## <dbl> <dbl> <chr> <dbl> <chr> <dttm>
## 1 -118. 51.3 GLACIER NP ROGERS PASS 1173191 1173~ 1965-06-01 00:00:00
## # ... with 30 more variables: PROVINCE_CODE <chr>, LOCAL_YEAR <dbl>,
## # LOCAL_MONTH <dbl>, LOCAL_DAY <dbl>, MEAN_TEMPERATURE <dbl>,
## # MEAN_TEMPERATURE_FLAG <chr>, MIN_TEMPERATURE <dbl>,
## # MIN_TEMPERATURE_FLAG <chr>, MAX_TEMPERATURE <dbl>,
## # MAX_TEMPERATURE_FLAG <chr>, TOTAL_PRECIPITATION <dbl>,
## # TOTAL_PRECIPITATION_FLAG <chr>, TOTAL_RAIN <dbl>, TOTAL_RAIN_FLAG <chr>,
## # TOTAL_SNOW <dbl>, TOTAL_SNOW_FLAG <chr>, SNOW_ON_GROUND <dbl>, ...
# Desde un archivo de github covid_global
df4 <- read_csv("https://raw.githubusercontent.com/CSSEGISandData/COVID-19/master/csse_covid_19_data/csse_covid_19_time_series/time_series_covid19_confirmed_global.csv")
head(df4, 1)## # A tibble: 1 x 765
## `Province/State` `Country/Region` Lat Long `1/22/20` `1/23/20` `1/24/20`
## <chr> <chr> <dbl> <dbl> <dbl> <dbl> <dbl>
## 1 <NA> Afghanistan 33.9 67.7 0 0 0
## # ... with 758 more variables: `1/25/20` <dbl>, `1/26/20` <dbl>,
## # `1/27/20` <dbl>, `1/28/20` <dbl>, `1/29/20` <dbl>, `1/30/20` <dbl>,
## # `1/31/20` <dbl>, `2/1/20` <dbl>, `2/2/20` <dbl>, `2/3/20` <dbl>,
## # `2/4/20` <dbl>, `2/5/20` <dbl>, `2/6/20` <dbl>, `2/7/20` <dbl>,
## # `2/8/20` <dbl>, `2/9/20` <dbl>, `2/10/20` <dbl>, `2/11/20` <dbl>,
## # `2/12/20` <dbl>, `2/13/20` <dbl>, `2/14/20` <dbl>, `2/15/20` <dbl>,
## # `2/16/20` <dbl>, `2/17/20` <dbl>, `2/18/20` <dbl>, `2/19/20` <dbl>, ...
Para importar datos, se tiene dos opciones desde el área de Environment/Import Dataset.
knitr::include_graphics('./img/import.png')FIGURA 2: Importar datos desde el directorio
Al seleccionar, por ejemplo From Text (readr) se puede importar datos con formato .csv, .tsv, .txt.
knitr::include_graphics('./img/importview.png')FIGURA 3: Importar datos tipo .csv, .txt, .tsv desde el directorio
Sin embargo, este procedimiento se recomienda utilizar solamente para archivos múltiples o grandes; en ese caso es mejor utilziar instrucciones con códigos.
Se tiene documentos con diferentes extensiones, para ello se tienen paquetes y funciones que permiten importar estos archivos.
.csv, .txtPara importar archivos con código se utiliza el paquete readr que soporta la carga de los siguientes tipos de formatos.
| Tipo de dato | Instrucción |
|---|---|
| Separado por coma (CSV) (coma, punto y coma, espacio blanco) | read_csv() |
| Separado por tab (TSV) | read_tsv() |
| Delimitación general | read_delim() |
| Con ancho fijo | read_fwf() |
| Tipo tabular separados por espacios en blanco | read_table() |
| Archivos web tipo log | read_log() |
Una alternativa a la read_formato() es la función fread() del paquete data.table el cual es una versión mejorada de data.frame .
# Guardar data de un archivo csv
getwd()## [1] "D:/GDrive/IKIAM/CLASES/2021II/2021II_GBI6/2021II_Clases/2021II_R/2021II_4.1_IntroduccionR_TiposDatos"
df_neutrophils <- read.csv("data/neutrophils.csv")
head(df_neutrophils,2)## DMSO TGX.221 PI103 Akt1
## 1 144.4393 99.61073 41.95241 111.8013
## 2 135.7167 115.35760 57.46430 124.1805
# Guardar data de un archivo tsv
df_chrdata <- read.csv("data/chr_data.txt")
head(df_chrdata,2)## chr.position.GM06990_ABL1.GM06990_MLLT3
## 1 8\t1\t-0.046610519\t-0.181629164
## 2 8\t100001\t0.256050886\t0.462550726
df_chrdata <- read_tsv("data/chr_data.txt")
head(df_chrdata,2)## # A tibble: 2 x 4
## chr position GM06990_ABL1 GM06990_MLLT3
## <dbl> <dbl> <dbl> <dbl>
## 1 8 1 -0.0466 -0.182
## 2 8 100001 0.256 0.463
# Guardar data de un archivo delim
df_brainBodyWeight <- read_delim("data/brain_bodyweight.txt", delim ="\t")
head(df_brainBodyWeight,2)## # A tibble: 2 x 6
## Species Category body brain log.brain log.body
## <chr> <chr> <dbl> <dbl> <dbl> <dbl>
## 1 Cow Domesticated 465 423 8.72 8.86
## 2 Grey Wolf Wild 36.3 120. 6.90 5.18
# Guardar data de un archivo grande
library(data.table)
df_eeh1997 <- fread("data/EEH_1997.csv")
head(df_eeh1997,2)## d_r codestad proubies canubies parubies estsalud claestsa tipestsa entestsa
## 1: NA EEH 1 1 50 2 10 3 8
## 2: NA EEH 1 1 50 2 10 3 8
## secestsa bolestsa aniestad mesestad ordegrpa conedadp edapacie sexpacie
## 1: 2 1 1997 1 1 3 48 2
## 2: 2 1 1997 1 2 3 84 2
## prorespa canrespa parrespa diaingpa mesingpa aniingpa diaegrpa mesegrpa
## 1: 1 1 50 30 12 1996 1 1
## 2: 1 1 50 31 12 1996 1 1
## diaestad conegrpa cau9nare cau307r9 cau050r9
## 1: 2 1 0091 16 1
## 2: 1 1 7840 468 600
# Comparación de tiempo fread() vs csv.read()
tiempo_fread <- system.time(fread("data/EEH_1997.csv"))
tiempo_readcsv <- system.time(read.csv("data/EEH_1997.csv"))
df_tiempo <- rbind(tiempo_fread, tiempo_readcsv)
df_tiempo## user.self sys.self elapsed user.child sys.child
## tiempo_fread 0.58 0.06 0.42 NA NA
## tiempo_readcsv 8.66 0.28 9.11 NA NA
print(paste("fread() es", round(df_tiempo[2,1]/df_tiempo[1,1],2), "veces más rápida que read.csv()"))## [1] "fread() es 14.93 veces más rápida que read.csv()"
.sasLos archivos .sas son un tipo de archivos estrucuturados que se leen con el software SAS. Se requiere instalar el paquete haven y utilizar la función read_sas(). Se puede encontrar ejemplos de archivos .sas en http://www.principlesofeconometrics.com/sas.htm.
# Guardar data de un archivo sas
#if(require("haven")) install.packages("haven")
library("haven")
df_sas <- read_sas('data/alcohol.sas7bdat')
head(df_sas, 3)## # A tibble: 3 x 4
## ADULTS KIDS INCOME CONSUME
## <dbl> <dbl> <dbl> <dbl>
## 1 2 2 758 1
## 2 2 3 1785 1
## 3 3 0 1200 1
spss .savR puede leer datos directamente de spss utilizando el paquete foreign con la la función read.spss() o el paquete haven y su función read_spss(). Se puede encontrar ejemplos de archivos .sav en http://spss.allenandunwin.com.s3-website-ap-southeast-2.amazonaws.com/data-files.html#.X3z_rXX0m00.
# Guardar data de un archivo csv
df_spss <- read_spss("data/sleep.sav")
head(df_spss, 1)## # A tibble: 1 x 55
## id sex age marital edlevel weight height healthrate fitrate
## <dbl> <dbl+lbl> <dbl> <dbl+lbl> <dbl+l> <dbl> <dbl> <dbl+lbl> <dbl+l>
## 1 83 0 [female] 42 2 [married/de~ 2 [sec~ 52 162 10 [very ~ 7
## # ... with 46 more variables: weightrate <dbl+lbl>, smoke <dbl+lbl>,
## # smokenum <dbl>, alchohol <dbl>, caffeine <dbl>, hourwnit <dbl>,
## # hourwend <dbl>, hourneed <dbl>, trubslep <dbl+lbl>, trubstay <dbl+lbl>,
## # wakenite <dbl+lbl>, niteshft <dbl+lbl>, liteslp <dbl+lbl>,
## # refreshd <dbl+lbl>, satsleep <dbl+lbl>, qualslp <dbl+lbl>,
## # stressmo <dbl+lbl>, medhelp <dbl+lbl>, problem <dbl+lbl>,
## # impact1 <dbl+lbl>, impact2 <dbl+lbl>, impact3 <dbl+lbl>, ...
.xls .xlsxPar leer archivos excel, se tiene el paquete readxl con la la función read_excel() o el paquete xlsx y su función read.xlsx().
# Guardar data de un archivo xlsx o xls
#if(require("readxl")) install.packages("readxl")
library("readxl")
df_xlsx <- read_excel("data/poblacion.xlsx")
head(df_xlsx, 3)## # A tibble: 3 x 8
## Nro `First Name` `Last Name` Gender Country Age Date Id
## <dbl> <chr> <chr> <chr> <chr> <dbl> <chr> <dbl>
## 1 1 Dulce Abril Female United States 32 15/10/2017 1562
## 2 2 Mara Hashimoto Female Great Britain 25 16/08/2016 1582
## 3 3 Philip Gent Male France 36 21/05/2015 2587
En los datos con las cuales se trabaja usualmente, se tiene elementos que pueden estar desordenados. El dato ordenado, tidy data, ayuda a optimizar el tiempo en el análisis de datos y tiene las siguientes características:
Cada columna es una variable
Cada fila es una observación
Cada celda tiene un único valor
knitr::include_graphics('./img/tidystr.png')FIGURA 4: Características del dato ordenado (tidy data)
La librería tidyr es la que se utiliza para ordenar los datos. Las funciones de esta librería se agrupan en algunas categorías:
Pivotting, sirven para convertir a datos extensos en compactos o viceversa, para ello se tienen las funciones pivot_longer(), pivot_wider() que son equivalentes a las funciones anbteriores gather() y spread() respectivamente.
Rectangling, ordenan tablas altamente anidados en datos ordenados, para ello se tienen las funciones unnest_longer(), unnest_wider() y hoist().
Nesting, se convierte datos agrupados donde cada grupo se convierte en una columan, para ello se utilizan las funciones nest() y unnest.
Splitting y comdinación de columnas de character, se utiliza separate() y extract() que separa una columna simple de character a columnas múltiples; por otro lado se utiliza unite() para reagrupar columnas de character.
Valores ausentes, convertir en valores explícitos con complete(), anularlos con drop_na(), reemplazar con valores previos o posteriores con fill() o cambiar por un valor con replace_na.
En esta etapa lo que se busca es ordenar los datos y además de limpiar o corregir las mismas.
%>%El operador pipe %>% equivale a un agregador (+) de procesos. Por ejemplo si se tiene un dataframe se realiza una agrupación, luego se realiza un suma, luego se evalua un promedio, entonces esta secuencia de procesos se podría resumir como:
dataframe %>% agrupacion %>% suma() %>% promedio
Este operador es altamente utilizado para procesar datos con las librerías de tidyverse. El operador pipe evita tener confusiones como cuando se tiene muchos procesos con ( ), como por ejemplo la operación:
# Se tiene e siguiente vector
valores <- c(0.109, 0.359, 0.63, 0.996, 0.515, 0.142, 0.017, 0.829, 0.907)
# Se realiza las operaciones en el siguiente orden: logaritmo, coseno, exponencial, redondeo y orden
sort(round(exp(cos(log(valores))), 1))## [1] 0.5 0.6 0.7 1.7 2.2 2.4 2.7 2.7 2.7
# Utilizanzando el operador pipe se tendría lo siguiente:
# valores %>% logaritmo %>% coseno %>% exponencial %>% redondeo %>% orden
valores_piped <- valores %>% log() %>% cos() %>% exp() %>% round(1) %>% sort()
valores_piped## [1] 0.5 0.6 0.7 1.7 2.2 2.4 2.7 2.7 2.7
Como se evidencia, al utilizar el operador %>% se facilita diferenciar como es la secuencia de procesamiento de la data.
knitr::include_graphics('./img/tidyv-flow.png')FIGURA 5: Operador pipe %>% en tidyverse y sus librerías
path <- "https://raw.githubusercontent.com/martintinch0/CienciaDeDatosParaCuriosos/master/data/gapminder.csv"
df_gapminder <- read.table(file = path, sep=';', header = TRUE, stringsAsFactors = FALSE)
# pivot_longer
library("tidyr")
df_gapminder2 <- df_gapminder %>% pivot_longer(!c(country, continent), names_to = "datos", values_to = "valor")
# pivot_wider
df_gapminder3 <- df_gapminder2 %>% pivot_wider(names_from = "datos", values_from = "valor", values_fn = list)
# Separate
df_gapminder4 <- df_gapminder3 %>% separate(year, paste0("A_", 1:13))
# Extract
df6 <- data.frame(x = c(NA, "a-b", "a-d", "b-c", "d-e"))
df7 <- df6 %>% extract(x, c("A", "B"), "([a-d]+)-([a-d]+)")
# Valores ausentes
df_neutrophils2 <- df_neutrophils %>% drop_na(DMSO, any_of("Akt1"))
colnames(df_neutrophils2)## [1] "DMSO" "TGX.221" "PI103" "Akt1"
df_neutrophils3 <- df_neutrophils2 %>% replace_na(list(TGX.221=0))
df_neutrophils4 <- df_neutrophils3 %>% fill(PI103, .direction = "down")Después de tener la data ordenada (tidy data) se requiere hacer procesamientos de cálculo, selección, filtrado, resumen o rearreglo. Estas operaciones se pueden implementar utilizando la librería dplyr. Esta librería tiene las siguientes opciones:
| Función | Descripción |
|---|---|
mutate() |
Adiciona nuevas variables basados en las operaciones con otras columnas |
select() |
Selecciona variables basados en sus nombres |
filter() |
Selecciona casos basados en valores condicionados |
summarise() |
Reduce los múltiples valores en una tabla resumen |
arrange() |
Cambia el orden de las filas |
group_by() |
Permite operar por grupos |
select()El comando select() permite seleccionar columnas de data frames utilizando solamente los nombres de las variables deseadas.
library(ggplot2) # librería de visualizacion que tiene datasets adicionales como "diamond"
library(dplyr)
# Data inicial
df_diamonds <- diamonds
colnames(df_diamonds)## [1] "carat" "cut" "color" "clarity" "depth" "table" "price"
## [8] "x" "y" "z"
# Data de columnas seleccionadas
df_diamonds_clar <- df_diamonds %>% select(cut, clarity, price)
colnames(df_diamonds_clar)## [1] "cut" "clarity" "price"
# Formas de generar vectores con una columna de dataframe
diamonds_precio <- df_diamonds$price
str(diamonds_precio)## int [1:53940] 326 326 327 334 335 336 336 337 337 338 ...
diamonds_cut <- df_diamonds %>% pull(cut) # crear vector con pull()
diamonds_color <- df_diamonds %>% select(color) %>% unlist() # crear vector con unlist()
# Elementos únicos en una columna
length(unique(diamonds_color))## [1] 7
filter()La función filter() permite seleccionar datos de acuerdo a los que toman en una o más variable.
# Filtro de diamond_df con corte "cut" == "fair"
df_diamonds_fair <- df_diamonds %>% filter (cut == "Fair")
summary(df_diamonds_fair)## carat cut color clarity depth
## Min. :0.220 Fair :1610 D:163 SI2 :466 Min. :43.00
## 1st Qu.:0.700 Good : 0 E:224 SI1 :408 1st Qu.:64.40
## Median :1.000 Very Good: 0 F:312 VS2 :261 Median :65.00
## Mean :1.046 Premium : 0 G:314 I1 :210 Mean :64.04
## 3rd Qu.:1.200 Ideal : 0 H:303 VS1 :170 3rd Qu.:65.90
## Max. :5.010 I:175 VVS2 : 69 Max. :79.00
## J:119 (Other): 26
## table price x y
## Min. :49.00 Min. : 337 Min. : 0.000 Min. : 0.000
## 1st Qu.:56.00 1st Qu.: 2050 1st Qu.: 5.630 1st Qu.: 5.570
## Median :58.00 Median : 3282 Median : 6.175 Median : 6.100
## Mean :59.05 Mean : 4359 Mean : 6.247 Mean : 6.183
## 3rd Qu.:61.00 3rd Qu.: 5206 3rd Qu.: 6.700 3rd Qu.: 6.640
## Max. :95.00 Max. :18574 Max. :10.740 Max. :10.540
##
## z
## Min. :0.000
## 1st Qu.:3.610
## Median :3.970
## Mean :3.983
## 3rd Qu.:4.280
## Max. :6.980
##
# Filtro de diamond_df con corte "cut" == "fair" y "price" <= 4000
df_diamonds_fair_cheap <- df_diamonds %>% filter (cut == "Fair" & price <= 4000)
summary(df_diamonds_fair_cheap)## carat cut color clarity depth
## Min. :0.220 Fair :979 D: 97 SI2 :273 Min. :43.00
## 1st Qu.:0.595 Good : 0 E:146 SI1 :241 1st Qu.:63.95
## Median :0.730 Very Good: 0 F:201 VS2 :157 Median :65.00
## Mean :0.766 Premium : 0 G:197 I1 :131 Mean :63.98
## 3rd Qu.:0.960 Ideal : 0 H:162 VS1 :108 3rd Qu.:65.90
## Max. :1.520 I:108 VVS2 : 49 Max. :79.00
## J: 68 (Other): 20
## table price x y z
## Min. :49.0 Min. : 337 Min. :3.870 Min. :3.780 Min. :2.32
## 1st Qu.:56.0 1st Qu.:1386 1st Qu.:5.390 1st Qu.:5.335 1st Qu.:3.33
## Median :58.0 Median :2318 Median :5.790 Median :5.740 Median :3.66
## Mean :59.2 Mean :2274 Mean :5.718 Mean :5.656 Mean :3.64
## 3rd Qu.:61.0 3rd Qu.:3050 3rd Qu.:6.140 3rd Qu.:6.070 3rd Qu.:3.98
## Max. :79.0 Max. :3992 Max. :7.260 Max. :7.130 Max. :4.80
##
# Filtro de diamond_df con corte "cut" == "fair" y "price" <= 4000 o color !=c("G", "E")
df_diamonds_multfiltro <- df_diamonds %>% filter (cut == "Fair" & price <= 4000 | color !=c("G", "E"))
summary(df_diamonds_multfiltro)## carat cut color clarity depth
## Min. :0.2000 Fair : 1514 D:6775 SI1 :10930 Min. :43.00
## 1st Qu.:0.4000 Good : 4030 E:4981 VS2 : 9869 1st Qu.:61.10
## Median :0.7100 Very Good: 9721 F:9542 SI2 : 7652 Median :61.90
## Mean :0.8168 Premium :11173 G:5789 VS1 : 6489 Mean :61.76
## 3rd Qu.:1.0600 Ideal :17183 H:8304 VVS2 : 3830 3rd Qu.:62.50
## Max. :5.0100 I:5422 VVS1 : 2834 Max. :79.00
## J:2808 (Other): 2017
## table price x y
## Min. :43.00 Min. : 326 Min. : 0.000 Min. : 0.000
## 1st Qu.:56.00 1st Qu.: 968 1st Qu.: 4.730 1st Qu.: 4.740
## Median :57.00 Median : 2513 Median : 5.730 Median : 5.740
## Mean :57.49 Mean : 4008 Mean : 5.773 Mean : 5.776
## 3rd Qu.:59.00 3rd Qu.: 5395 3rd Qu.: 6.580 3rd Qu.: 6.570
## Max. :95.00 Max. :18823 Max. :10.740 Max. :58.900
##
## z
## Min. : 0.000
## 1st Qu.: 2.930
## Median : 3.540
## Mean : 3.565
## 3rd Qu.: 4.050
## Max. :31.800
##
# Filtro de df_spss con is.na(age)
colnames(df_spss)## [1] "id" "sex" "age" "marital" "edlevel"
## [6] "weight" "height" "healthrate" "fitrate" "weightrate"
## [11] "smoke" "smokenum" "alchohol" "caffeine" "hourwnit"
## [16] "hourwend" "hourneed" "trubslep" "trubstay" "wakenite"
## [21] "niteshft" "liteslp" "refreshd" "satsleep" "qualslp"
## [26] "stressmo" "medhelp" "problem" "impact1" "impact2"
## [31] "impact3" "impact4" "impact5" "impact6" "impact7"
## [36] "stopb" "restlss" "drvsleep" "drvresul" "ess"
## [41] "anxiety" "depress" "fatigue" "lethargy" "tired"
## [46] "sleepy" "energy" "stayslprec" "getsleprec" "qualsleeprec"
## [51] "totsas" "cigsgp3" "agegp3" "probsleeprec" "drvslprec"
df_spss_isna <- df_spss %>% filter (is.na(age))
dim(df_spss_isna)## [1] 23 55
# Filtro de df_spss con age entre 12 y 30
df_spss_joven <- df_spss %>% filter (between(age, 12, 30))
dim(df_spss_joven)## [1] 44 55
# Filtro de df_spss con edlevel de 3 y 4
df_spss_educ <- df_spss %>% filter (edlevel %in% c(3,4))
dim(df_spss_educ)## [1] 101 55
arrange()La función arrange() permite ordenar los datos en orden ascendente o descendente en base a los valores de las variables. Es informativo porque se puede revisar los valores extermos.
# df_gapminder ordenado por "gdpPercap"
df_gapminder_asc <- df_gapminder %>% arrange (gdpPercap)
head(df_gapminder_asc,5)## country continent year lifeExp pop gdpPercap
## 1 Congo, Dem. Rep. Africa 2002 44.966 55379852 241.1659
## 2 Congo, Dem. Rep. Africa 2007 46.462 64606759 277.5519
## 3 Lesotho Africa 1952 42.138 748747 298.8462
## 4 Guinea-Bissau Africa 1952 32.500 580653 299.8503
## 5 Congo, Dem. Rep. Africa 1997 42.587 47798986 312.1884
# df_gapminder ordenado por "gdpPercap" en forma descendente
df_gapminder_desc <- df_gapminder %>% arrange(desc(gdpPercap))
head(df_gapminder_desc,5)## country continent year lifeExp pop gdpPercap
## 1 Kuwait Asia 1957 58.033 212846 113523.13
## 2 Kuwait Asia 1972 67.712 841934 109347.87
## 3 Kuwait Asia 1952 55.565 160000 108382.35
## 4 Kuwait Asia 1962 60.470 358266 95458.11
## 5 Kuwait Asia 1967 64.624 575003 80894.88
# df_gapminder filtrado por "Americas" y ordenado por "gdpPercap" en forma descendente
df_gapminder_AmerDesc <- df_gapminder %>% filter(continent == "Americas") %>% arrange(desc(gdpPercap))
head(df_gapminder_AmerDesc,5)## country continent year lifeExp pop gdpPercap
## 1 United States Americas 2007 78.242 301139947 42951.65
## 2 United States Americas 2002 77.310 287675526 39097.10
## 3 Canada Americas 2007 80.653 33390141 36319.24
## 4 United States Americas 1997 76.810 272911760 35767.43
## 5 Canada Americas 2002 79.770 31902268 33328.97
mutate()La función mutate() permite crear nuevas variables como resultado de operar otras variables del dataframe. La función tiene la siguiente forma: ...%>% mutate(nombre_columna_nueva = valor_calculado)
# df_iris calcular area del sépalo
df_iris <- iris
df_iris_areasep <- df_iris %>% mutate (area_sepal = Sepal.Length*Sepal.Width)
head(df_iris_areasep,5)## Sepal.Length Sepal.Width Petal.Length Petal.Width Species area_sepal
## 1 5.1 3.5 1.4 0.2 setosa 17.85
## 2 4.9 3.0 1.4 0.2 setosa 14.70
## 3 4.7 3.2 1.3 0.2 setosa 15.04
## 4 4.6 3.1 1.5 0.2 setosa 14.26
## 5 5.0 3.6 1.4 0.2 setosa 18.00
group_by() y summary()La función group_by() permite agrupar las filas en base a las categorías de alguna variable; luego de agrupar se puede aplicar una transformación - cálculo con la función summary(). Esta combinación tiene la siguiente forma: data %>% group_by(variable) %>% summarise(nombre_tranformacion= valor_calculado)
# df_msleep agrupado por orden y calculado el promedio de horas de sueño
df_msleep <- msleep
df_msleep_group <- df_msleep %>% group_by (order) %>% summarise(sleept_mean = signif(mean(sleep_total, na.rm = TRUE),2))
df_msleep_group %>% arrange(sleept_mean)## # A tibble: 19 x 2
## order sleept_mean
## <chr> <dbl>
## 1 Perissodactyla 3.5
## 2 Proboscidea 3.6
## 3 Artiodactyla 4.5
## 4 Cetacea 4.5
## 5 Hyracoidea 5.7
## 6 Lagomorpha 8.4
## 7 Monotremata 8.6
## 8 Scandentia 8.9
## 9 Carnivora 10
## 10 Erinaceomorpha 10
## 11 Primates 10
## 12 Soricomorpha 11
## 13 Diprotodontia 12
## 14 Rodentia 12
## 15 Pilosa 14
## 16 Afrosoricida 16
## 17 Cingulata 18
## 18 Didelphimorphia 19
## 19 Chiroptera 20
# df_msleep agrupado por dieta, se calcula número de individuos, index_brainwt/bodywt, awake_mean y sleep_mean
colnames(df_msleep)## [1] "name" "genus" "vore" "order" "conservation"
## [6] "sleep_total" "sleep_rem" "sleep_cycle" "awake" "brainwt"
## [11] "bodywt"
df_msleep_brain <- df_msleep %>% group_by(vore) %>%
summarise(muestra = length(vore),
index_brain_body = mean(brainwt/bodywt, na.rm = TRUE),
awake_mean = mean(awake),
sleep_mean = mean(sleep_total))
df_msleep_brain## # A tibble: 5 x 5
## vore muestra index_brain_body awake_mean sleep_mean
## <chr> <int> <dbl> <dbl> <dbl>
## 1 carni 19 0.00711 13.6 10.4
## 2 herbi 32 0.00718 14.5 9.51
## 3 insecti 5 0.0122 9.06 14.9
## 4 omni 20 0.0155 13.1 10.9
## 5 <NA> 7 0.00974 13.8 10.2
join()Al tener dos o más datos donde una o varias columnas coinciden, con la función join() se integra nueva información en base a una (o más) columnas en las que coinciden. Se tiene cuatro tipos de join():
inner_join() retorna las columnas que coinciden entre ambos.
left_join() retorna las columnas de x y las columnas que coinciden entre x e y.
right_join() retorna las columnas de y y las columnas que coinciden entre x e y.
full_join()retorna las columnas de x e y.
La forma genérica de la función join es la siguiente:
tipo_join(x, y, by = NULL, copy = FALSE, suffix = c(".x", ".y"), ...)
Las celdas que no tienen coincidencia son rellenadas con NA.
# Datos
areas_inv <- data.frame(InvId = sample(1:20, 20, replace=FALSE),
Product = sample(c("Genomica","Agua","Rocas",
"Anfibios"), 20, replace = TRUE),
Tesistas = sample (1:4, 10, replace = TRUE))
institucion <- data.frame(InvId = sample(1:20, 15, replace=FALSE),
Instituto = sample(c("Ikiam","YachayTech","EPN", "ESPOCH",
"USFQ"), 15, replace = TRUE),
Fondos = sample(c("Institucional","Nacional","Internacional"),
15, replace = TRUE))
# inner_join()
invest_inner <- areas_inv %>% inner_join(institucion, by = "InvId")
dim(invest_inner)## [1] 15 5
# left_join()
invest_leftj <- areas_inv %>% left_join(institucion, by = "InvId")
dim(invest_leftj)## [1] 20 5
# right_join()
invest_rightj <- areas_inv %>% right_join(institucion, by = "InvId")
dim(invest_rightj)## [1] 15 5
# full_join()
invest_fullj <- areas_inv %>% full_join(institucion, by = "InvId")
dim(invest_fullj)## [1] 20 5
data.tabledata.table es un paquete de R que premite manipular datos con las operaciones de subset, group, update, join y otras operaciones. Esta librería permite que se opere con mayor eficiencia en el memoria y tiempo de computación. Es recomendable cuando se tiene datos grandes las cuales se cargan con la instrucción fread(). Si se desea crear una tabla la instrucción tiene una estructura similar al nombre <- data.frame (parámetros), en su lugar es nombre <- data.table (parámetros).
# Datos predeterminados
library(data.table)
df_fligths <- fread("https://raw.githubusercontent.com/Rdatatable/data.table/master/vignettes/flights14.csv")
colnames(df_fligths)## [1] "year" "month" "day" "dep_delay" "arr_delay" "carrier"
## [7] "origin" "dest" "air_time" "distance" "hour"
# Subset
unique(df_fligths$dest)## [1] "LAX" "PBI" "MIA" "SEA" "SFO" "BOS" "ORD" "IAH" "AUS" "DFW" "STT" "SJU"
## [13] "LAS" "MCO" "EGE" "CHS" "FLL" "RSW" "BTV" "BUF" "IAD" "PWM" "SYR" "RDU"
## [25] "JAX" "HOU" "DEN" "ROC" "SAN" "BQN" "LGB" "PSE" "TPA" "PHX" "SMF" "SRQ"
## [37] "SJC" "SLC" "ABQ" "OAK" "BUR" "PDX" "MSY" "CLT" "ATL" "DTW" "MSP" "DAY"
## [49] "MHT" "DCA" "SDF" "CLE" "STL" "MEM" "BNA" "GSP" "MSN" "OMA" "IND" "RIC"
## [61] "PVD" "AVL" "MCI" "OKC" "MKE" "TUL" "PIT" "SAV" "BWI" "GSO" "GRR" "DSM"
## [73] "CVG" "ORF" "BHM"
## [ reached getOption("max.print") -- omitted 34 entries ]
df_fligths_chic <- df_fligths[origin == "JFK" & dest == "JAX" & month == 6L]
dim(df_fligths_chic)## [1] 87 11
# Ordenar
unique(df_fligths$origin)## [1] "JFK" "LGA" "EWR"
df_fligths_ord <- df_fligths[order(origin, -air_time)] # descendente para air_time
head(df_fligths_ord, 5)## year month day dep_delay arr_delay carrier origin dest air_time distance
## 1: 2014 3 2 24 87 UA EWR HNL 706 4963
## 2: 2014 3 4 -1 61 UA EWR HNL 697 4963
## 3: 2014 1 26 13 58 UA EWR HNL 688 4963
## 4: 2014 2 26 5 90 UA EWR HNL 676 4963
## 5: 2014 2 15 6 44 UA EWR HNL 674 4963
## hour
## 1: 9
## 2: 9
## 3: 9
## 4: 9
## 5: 9
# Selecccionar filas
df_fligths_fila <- df_fligths[5:7]
df_fligths_fila## year month day dep_delay arr_delay carrier origin dest air_time distance
## 1: 2014 1 1 2 1 AA JFK LAX 350 2475
## 2: 2014 1 1 4 0 AA EWR LAX 339 2454
## 3: 2014 1 1 -2 -18 AA JFK LAX 338 2475
## hour
## 1: 13
## 2: 18
## 3: 21
# Selecccionar columnas
df_fligths_columna <- df_fligths[5:7, 7:11]
df_fligths_columna## origin dest air_time distance hour
## 1: JFK LAX 350 2475 13
## 2: EWR LAX 339 2454 18
## 3: JFK LAX 338 2475 21
df_fligths_columna <- df_fligths[1:7, .(dep_delay,arr_delay,carrier)]
df_fligths_columna## dep_delay arr_delay carrier
## 1: 14 13 AA
## 2: -3 13 AA
## 3: 2 9 AA
## 4: -8 -26 AA
## 5: 2 1 AA
## 6: 4 0 AA
## 7: -2 -18 AA
selectores <- c("origin", "dest", "air_time")
df_fligths_selector <- df_fligths[1:7, ..selectores]
df_fligths_selector## origin dest air_time
## 1: JFK LAX 359
## 2: JFK LAX 363
## 3: JFK LAX 351
## 4: LGA PBI 157
## 5: JFK LAX 350
## 6: EWR LAX 339
## 7: JFK LAX 338
# Número de vuelos queno tuvieron delay (>0)
df_fligths_calc <- df_fligths[, sum((dep_delay+arr_delay)>0)]
df_fligths_calc## [1] 108239
# Agrupar
flight_group <- df_fligths[, .N, by = .(origin, carrier)]
flight_group## origin carrier N
## 1: JFK AA 11923
## 2: LGA AA 11730
## 3: EWR AA 2649
## 4: EWR AS 574
## 5: JFK B6 34220
## 6: EWR B6 5473
## 7: LGA B6 4786
## 8: LGA DL 18670
## 9: EWR DL 4153
## 10: JFK DL 18860
## 11: EWR EV 28328
## 12: LGA EV 10422
## 13: LGA F9 473
## 14: LGA FL 1251
## 15: JFK HA 260
## 16: LGA MQ 12948
## 17: JFK MQ 5444
## 18: JFK VX 3138
## 19: EWR VX 1644
## 20: EWR WN 4807
## 21: LGA WN 7095
## 22: EWR MQ 167
## 23: JFK EV 1069
## 24: EWR UA 36124
## 25: LGA UA 6219
## [ reached getOption("max.print") -- omitted 8 rows ]
flight_mean <- df_fligths[dest == "MIA", .(mean_arrdelay = mean(arr_delay),
mean_depdelay = mean(dep_delay)),
by = .(origin, dest, month)]
dim(flight_mean)## [1] 30 5
En conclusión data.table es una forma rápida de manipular y transformar data grande. Puede revisar todas las funcionalidades de ese paquete en su página de referencia: https://rdatatable.gitlab.io/data.table/.
Realice las siguientes actividades en un documento .Rmd
Utilizando las librerías RCurl, readr, readxl y data.table cargue los siguientes archivos asignando indetificadores adecuados:
Busque un archivo tipo .txt o .csv en GitHub (https://github.com) que se relacione a alguna area y que esté asociado al uso de R para su análisis.
Cargue el archivo “expr_data.txt” de la carpeta data
Cargue el archivo “SEST17_micro_35755_20191209_CSV.csv” de la carpeta data utilizando fread() y read.csv y compare los tiempos que requieren para cargar el archivo.
Cargue el archivo “barriosOriginal” desde el url.
Asigne a un data frame la data precargada de R mpg, puede requerir la librería ggplot2.
# Coloque aquí las librerías
# Escriba aquí las instrucciones para cargar los archivos. Utilice la librería tidyr para arreglar la información cargada en el paso 5.1.
# Coloque aquí las librerías
# Escriba aquí las instrucciones para obtener un tidy data.
# Puede requerir anular datos tipo "NaN" o "NA"dplyr o data.table con la data de mpg y barriosOriginal:Seleccionar select()
Filtrar filter()
Ordenar arrange()
Calcular mutate()
Agrupar y resumir group_by y summarise()
..._join().# Coloque aquí las librerías
# Escriba aquí las instrucciones para procesar la data.
# Escriba aquí las instrucciones para usar la función ..._join()